lambda表达式,称为匿名函数,是一种函数字面值,也就是没有声明的函数,但可以作为表达式传递出去.而已lambda表达式或者匿名函数作为函数参数的函数,就是高阶函数
一 函数类型的声明:
在kotlin中,声明一个函数类型的格式很简单,在kotlin中我们是通过->符号来组织参数类型和返回值类型,左右是函数的参数,右边是函数的返回值,函数的参数,必须在()中,多个参数的时候,用,将参数分开。如下:
(Int)->Int
?
(Int,Stirng)->Int
那没有函数参数,和无返回值函数怎么声明?如下:
()->Int
?
()->Unit
接下来看看高阶函数参数里函数参数类型的表达:
fun gaojiefun(funParam:(Int)->Int,param:Int){}
如果高阶函数里的参数也是高阶函数,那这个又如何表达呢?
private fun gaojiefun(funParams:((Int)->Int)->Int){}
二 函数的传入
前面我们已经知道了高阶函数函数参数类型的声明,那我们再使用高阶函数的时候,如何传入呢?原始的方法就是创建一个函数,然后传入这个函数引用的方法,但是我们知道,Kotlin有很多语法糖,这里就用到了kotlin中的匿名函数和Lambda表达式
匿名函数: 来讲匿名函数,看定义就知道这是一个没有名字的’函数’,注意这里的’函数’这两个字是带有引号的。首先来看看怎么在高阶函数中使用吧。
//接着上面的例子讲 //除了这种通过引用对象调用testHighFun(funObject)的方法,还可以直接把一个函数当做这个高阶函数的参数。
val param = fun (param:Int){
}
gaojiefun(param)
注意:通过之前的分析,我们可以知道,这个高阶函数gaojiefun接收的参数是一个函数对象的引用,也就是说我们定义的val param是一个函数对象的引用,那么可以得出这个匿名’函数’ fun(param:Int){},他的本质是一个函数对象。他并不是’函数’。我们可以看一下反编译出来的java代码
Function1 param = (Function1)null.INSTANCE;
this.gaojiefun(param);
所以重点记住,Kotlin中的匿名函数,它的本质不是函数。而是对象。它和函数不是一个东西,它是一个函数类型的对象。对象和函数,它们是两个东西。
Lambda表达式
Lambda 表达式的完整语法形式如下: val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
Lambda 表达式总是括在花括号中, 完整语法形式的参数声明放在花括号内,并有可选的类型标注, 函数体跟在一个 -> 符号之后。如果推断出的该Lambda 的返回类型不是 Unit,那么该 Lambda 主体中的最后一个(或可能是单个) 表达式会视为返回值。
我们知道,Kotlin里是有支持类型推导的,所以上面的表达式我们是可以再次简化的:
val sum= { x: Int, y: Int -> x + y }
val sum: (Int, Int) -> Int = { x, y -> x + y }
在kotlin中还支持,如果函数的最后一个参数是函数,那么作为相应参数传入的 Lambda 表达式可以放在圆括号之外:
gaojiefun(){
}
?
gaojiefun{
}
?
gaojiefun{
it.toString(it)
}
从 lambda 表达式中返回一个值
我们可以使用限定的返回语法从 lambda 显式返回一个值。 否则,将隐式返回最后一个表达式的值。参考官网的例子如下:
ints.filter {
val shouldFilter = it > 0
shouldFilter
}
?
ints.filter {
val shouldFilter = it > 0
return@filter shouldFilter
}
好了,以上就是Lambda的基本用法了。
讲了这么多,我们只是讲解了Lambda怎么使用,那么它的本质是什么?其实仔细思考一下上面的testHighFun可以传入一个Lambda表达式就可以大概知道,Lambda的本质也是一个函数类型的对象。这一点也可以通过发编译的java代码去看。
三 匿名函数与Lambda表达式的总结:
- 两者都能作为高阶函数的参数进行传递。
- 两者的本质都是函数类型的对象。
|