文章目录
- 一、尾随 Lambda - Trailing Lambda 语法
- 二、Kotlin 中使用 Lambda 表达式替代对象表达式原理
- 1、Lambda 替换对象表达式
- 2、原理分析
- 3、示例分析
一、尾随 Lambda - Trailing Lambda 语法
尾随 Lambda - Trailing Lambda 语法 : 满足如下两个条件 , 可以 使用 尾随 Lambda 语法 ;
- 函数作为参数 ,
- 并且 该函数参数 是最后一个参数 ,
那么可以 将最后一个参数 放在 括号外面 , 括号外使用 Lambda 表达式作为参数 ;
使用 尾随 Lambda 语法 可以使代码 更简洁 , 提高代码可读性 ;
示例说明 :
下面的函数 的最后一个参数 是 函数类型 ;
调用 foo 函数时 , 第二个参数是函数类型 , 并且该参数是函数的最后一个参数 ,
那么可以 使用 尾随 Lambda 语法 , 将 函数参数 移到括号外面 使用 Lambda 表达式表示 ;
正常调用方式如下 : 函数参数 放在 括号内进行传递 ;
使用 尾随 Lambda 语法 的调用方式 : 将第二个函数参数提取到括号外面 , 也就是将 Lambda 表达式 写在括号的外部 ;
二、Kotlin 中使用 Lambda 表达式替代对象表达式原理
1、Lambda 替换对象表达式
在使用 Kotlin 开发时 , 经常遇到这种情况 , 最后一个函数是匿名内部类 , 匿名内部类中只实现了一个函数 , 此时使用 Lambda 表达式替代该 匿名内部类 ;
如 : 为按钮添加点击事件 , 对应的 Java 代码是
翻译成 Kotlin 代码后为 : 使用对象表达式
更进一步简写为 :
2、原理分析
Kotlin 中的 对象表达式 ,
对应的就是 Java 中的 匿名内部类 ;
Lambda 表达式 其本质 就是 函数类型 的 匿名对象 , 也是一个实例对象 , 在堆内存中分配相应的空间 ;
在下面的代码中 , 使用 对象表达式 创建了匿名对象 , 该匿名类实现了 View.OnClickListener 接口 , 并实现了其中的 onClick 函数 ;
符合以下两个条件 :
- 函数 接收一个 接口类型 的匿名内部类 或 对象表达式 ;
- 该 接口类型 中 只定义了一个函数 ;
可以 省略掉 匿名内部类 也就是 对象表达式的定义 , 直接使用 接口中的函数 类型对象 , 也就是 Lambda 表达式 / 匿名函数 / 闭包 来替代该 接口类型 变量 ;
3、示例分析
View 组件设置 按钮点击事件 的函数原型如下 : View#setOnClickListener 函数 接收一个 OnClickListener 实例对象作为参数 ;
而 OnClickListener 是一个接口 , 接口中只有一个方法 ;
下面是为 View 组件设置 点击事件 时 , 输入 setOnClickListener 出现的代码提示 ;
View#setOnClickListener 可以设置两种参数 :
- OnClickListener 类型的对象表达式 :
- OnClickListener#onClick 函数类型的 Lambda 表达式 :
如果设置了 OnClickListener#onClick 函数类型的 Lambda 表达式 , 其 Lambda 表达式类型为
传入 View 类型实例对象 , 返回值为 void , 对应的就是 OnClickListener 接口中的 void onClick(View v);
函数类型 ;
如果 在 setOnClickListener 函数中设置了 (View) -> Unit 类型的 Lambda 表达式 ,
Kotlin 编译时会查找 setOnClickListener 函数真正接收的是 OnClickListener 接口实例对象 ,
传入一个 Lambda 表达式 , 会自动为其创建 OnClickListener 接口对应的匿名内部类 ,
并且将该 Lambda 表达式作为该匿名内部类的函数实体 ;
如果 传入的 Lambda 表达式类型 , 不符合 接口中的唯一的函数类型 ,
也就是再该示例中 Lambda 表达式类型不是 (View) -> Unit
类型的 , 就会在编译时报错 ,
报错信息如下 :
- 返回值设置错误 : 设置错误的返回值 , 会提示
-
参数设置错误 : 默认参数是
it:View!
, 如果设置成 it:String
, 就会报如下错误 ;