本节讨论 Kotlin 的 Lambda 闭包、以及它的声明和原理
我们先看一个 Java 中非常常见的例子,就是创建一个子线程:
我们知道 Java 8 也是有 Lambda 支持的,它可以把 Runnable 对象省略成一个 () ->
的表达形式。
接下来,我们看下 Kotlin 的 Lambda 形式,与 Java 8 Lambda 类似,只不过 ->
放在了 {}
的内部。
同时 Kotlin 的 Lambda 语法还有很多的特性,它允许你省略很多没有的信息。
比如,如果你的 Lambda 是没有参数的,你是可以省略 ->
符号的。示例中,Runnable 是没有参数的,可以写成如下形式:
接着,如果 Lambda 是函数的最后一个参数,可以将大括号放在小括号外面;
如果函数只有一个参数且这个参数是 Lambda,可以省略小括号。
这就是 Kotlin Lambda 中最简单的结构:
接下来看下单独声明一个闭包的时候它对应的写法:
首先给闭包声明一个变量名,同时用闭包声明给它赋值,闭包也是可以有参数的,参数声明与变量声明基本相同,变量名: 变量类型 -> Lambda 闭包体
。
通过示例可以看出,闭包调用分为两种形式,一种是直接使用小括号添加参数调用,另外一种方式是调用它的 invoke 方法。
首先,写一个带有一个参数的闭包:
接下来我们看下它对应的 Java 源码:
从转换的 Java 代码可以看出来,我们所写的闭包被转换成了 Function1 的类,实际上 Function1 是 Kotlin 标准库中的接口,我们打开 Functions.kt 文件:
翻到最后你会发现总共有 23 个接口,从 Function0 到 Function22,可以看出来接口名后面所跟的数字表示的是当前闭包所能接收的参数的个数,上面的示例中,我们传入了一个 Int 型参数,所以使用的是 Function1 接口。 难道只能接收 22 个参数以下闭包?下面我们再来看个示例:
我们声明了带有 23 个参数的闭包,之后看下 Java 源码:
会发现它使用 FunctionN 接口,使用数组作为参数巧妙地解决了 22 个以上参数的问题。
好,那我看下这个 FunctionN.kt 文件:
需要注意的是,在 Kotlin 1.3 之前确实只支持 22 个参数的闭包,而在 1.3 之后可以支持 N 个参数。
以上就是本节内容,欢迎大家关注~