高阶函数的定义
高阶函数和Lambda的关系是密不可分的。在之前的文章中,我们熟悉了Lambda编程的基础知识,并且掌握了一些与集合相关的函数式API的用法,如map
、filter
函数等。另外,我们也了解了Kotlin的标准函数,如run
、apply
函数等。
这些函数有一个共同的特点:它们都会要求传入一个Lambda表达式作为参数。像这种接收Lambda参数的函数就可以称为具有函数式编程风格的API,而如果你想要定义自己的函数式API,那就得借助高阶函数来实现了。
所以高阶函数的定义:如果一个函数接收另一个函数作为参数,或者返回值的类型是另一个函数,那么该函数就称为高阶函数。
这个定义可能有点不太好理解,一个函数怎么能接收另一个函数作为参数呢?这就涉及另外一个概念了:函数类型。我们知道,编程语言中有整型、布尔型等字段类型,而Kotlin又增加了一个函数类型的概念。如果我们将这种函数类型添加到一个函数的参数声明或者返回值声明当中,那么这就是一个高阶函数了。
定义一个函数类型
不同于定义一个普通的字段类型,函数类型的语法规则是有点特殊的,基本规则如下:
(String, Int) -> Unit
既然是定义一个函数类型,那么最关键的就是要声明该函数接收什么参数,以及它的返回值是什么。因此,->
左边的部分就是用来声明该函数接收什么参数的,多个参数之间使用逗号隔开,如果不接收任何参数,写一对空括号就可以了。而->
右边的部分用于声明该函数的返回值是什么类型,如果没有返回值就使用Unit
,它大致相当于Java中的void
。
现在将上述函数类型添加到某个函数的参数声明或者返回值声明上,那么这个函数就是一个高阶函数了,如下所示:
fun example(funExample: (String, Int) -> Unit) {
funExample("你好", 111)
}
如果是有返回值的,代码示例:
fun example(name: String, age: Int, getStudent: (String, Int) -> Student): Student {
return getStudent(name, age)
}
这里我们定义了一个getStudent的函数用来返回Student对象,那么我们就可以定义一个方法,代码如下:
fun gStudent(name:String,age: Int):Student{
val student=Student("001",1)
student.name=name
student.age=age
return student
}
然后调用:
val student= example("我的",12,::gStudent)
println("name=${student.name}------age=${student.age}")
打印结果:
你会发现,当我们需要返回值时,我们需要定义个方法来让高阶函数调用,这样是不是太麻烦了,Kotlin也考虑到了这一点,我们可以通过Lambda表达式、匿名函数、成员引用等。其中,Lambda表达式是最常见也是最普遍的高阶函数调用方式。
我们仍以上面的高阶函数为例,改成Lambda表达式,示例如下:
val student2 = example("张三", 12,) { name,age ->
val student =Student("",2)
student.name=name
student.age=age
student
}
println("name=${student2.name}------age=${student2.age}")
这样我们就不需要单独再去定义个函数来调用,我们可以直接在Lambda表达式中对参数进行操作,从而得到我们想要的数据