这是一个kotlin文件:
/**
- 比如说这样,我要给这个doFirst方法传一个执行过程,类型就是一个输入2个Int,输出一个Int的拉姆达表达式
*/
fun calculate(p1: Int, p2: Int, event1: (Int, Int) -> Int, event2: (Int, Int) -> Int) {
println(“执行doFirst”)
println(“执行event1 ${event1(p1, p2)}”)
println(“执行event2 ${event2(p1, p2)}”)
}
//测试lambda表达式
fun main() {
val sum = { x: Int, y: Int ->
print("求和 ")
x + y
}
val diff = { x: Int, y: Int ->
print("求差 ")
x - y
}
//kotlin里面,可以把拉姆达表示当作一个普通变量一样,去传递实参
calculate(p1 = 1, p2 = 2, event1 = sum, event2 = diff)
}
定义了一个calculate函数, p1,p2 是Int,而event1和event2 则是 lambda表达式. 高级语言特性,一等函数公民:函数本身可以被当作普通参数一样去传递,并且调用。那么, kotlin的lambda内核是怎么样的?
上图能够看出,
- calculate方法的后面2个参数,被编译成了 Function2 类型。
- 执行event1,event2,则是调用其invoke方法
- main函数中,出现了null.INSTANCE, 这里比较诡异,INSTANCE应该是用来获取实例的,但是为什么是null.INSTANCE
而看了Function2的源码,简直亮瞎了我的钛合金狗眼:
Function.kt文件中:
Function接口,Function2接口…Function22接口。好了,不要质疑谷歌大佬的设计思路,反正大佬写的就是对的…这里用22个接口(至于为什么是22个,猜想是谷歌觉得不会有哪个脑子秀逗的开发者真的弄22个以上的参数挤在一起吧),表示kotlin开发中可能出现的lambda表达式参数列表。
再举个栗子
给一个Button 设置点击事件,kotlin的写法是:
val btn = Button(this)
val lis = View.OnClickListener { println(“111”) }
btn.setOnClickListener(lis)
或者:
val btn = Button(this)
btn.setOnClickListener { println(“111”) }
setOnClickListener 方法的参数是 OnClickListener 接口:
public interface OnClickListener {
void onClick(View v);
}