声明高阶函数
-
高阶函数定义:是以另外一个函数作为参数或者返回值的函数;在Kotlin中可以用lambda或者函数引用来表示函数;
-
任何以lambda或者函数引用作为参数的函数,或者返回值为lambda或者函数引用的函数或者两者都满足的函数都是高阶函数;
-
声明函数类型:需要把函数参数类型放在括号中,紧接着是一个箭头和函数的返回类型(函数类型声明总是需要一个显式的返回类型,Unit类型的返回值不可忽略)
-
函数类型的返回值可以被标记为空,函数类型也可以为空,函数类型的参数名称不会影响类型的匹配;
-
在Java中使用函数类:Java 8中的lambda会被自动转换成函数类型的值;可以传递一个实现呢函数接口中的invoke方法的匿名类的实例(Java中使用函数类的原理是:函数类型被声明为普通的接口:一个函数类型的变量是FunctionN接口的一个实现,Kotlin标准库中定义了一系列的接口,Function0 没有参数的函数、Function1<P1, R> 一个参数的函数。。。每个接口都定义了一个Invoke方法)
-
函数类型的默认值:把lambda作为值放在=后
FunName : (Params...) -> Type = {...}
- 返回函数的函数:声明一个返回另一个函数的函数,需要指定一个函数类型作为返回类型
内联函数:销除lambda带来的运行开销
- 使用inline 时,它的函数体是内联的——函数体会直接替换到函数被调用的地方
- 内联函数的限制:如果lambda参数在某个地方被保存起来,以便后面可以继续使用,lambda表达式的代码将不会被内联
- 接收非内联lambda参数:noinline
- 决定如何将函数声明为内联:使用inline关键字只能提高带有Lambda参数的函数的性能
- 使用内联lambda管理资源:Kotlin标准库提供了叫作withLock的函数,它是Lock的扩展函数,实现加锁的功能(synchronized函数)
use函数:是一个扩展函数,被用来操作可关闭的资源,它接收一个lambda作为参数,这个方法调用lambda并且确保资源被关闭,不管lambda是正常执行还是抛出异常 - 对于普通函数的调用,JVM已经提供了强大的内联支持,它会分析代码的执行,并在任何通过内联能够带来好处的时候将函数调用内联,所以使用inline大多是在lambda表达式且符合内联条件。
高阶函数中的控制流
- 非局部返回:在lambda中使用关键字return,它会从调用lambda的函数中返回,并不只是从lambda中返回。条件:只有在以lambda作为参数的函数是内联函数的时候才能从更外层的函数返回。
- 从lambda返回(局部返回):终止lambda的执行,并接着从调用lambda的代码处执行,使用标签实现。使用:在lambda的花括号之前放一个标签名(可以是任何标识符),接着放一个@符号,从lambda返回,在return关键字后放一个@符号加标签名。
或者使用lambda作为参数的函数的函数名可以作为标签。
注意:一个lambda的表达式的标签不能多于一个; - 匿名函数默认使用局部返回:return从最近使用fun关键字声明的函数返回;匿名函数是省略了函数的名字以及参数的类型