以前有小伙伴反应 kotlin lambda与高阶函数 仍是有点云里雾里的,因此特地再补上一篇,学完这篇,相信你就真正的了解了kotlin中lambda与高阶函数的 本质了,也再也不惧怕使用了。java
在java中 是不容许 将函数做为参数传递的。 这个相信多数java开发者都知道。可是java是开了一个相似的口子的。 就是回调函数。 回调函数的目的 其实就是将函数 做为一个参数传递到另一个函数中。jvm
相似下面的代码: 函数
其实咱们传递进去的虽然表面看起来是一个对象,可是咱们使用的倒是这个对象中的 方法。post
因此实际上这样设计的意图就是将一个函数传递到另一个函数里面。设计
语法上虽然java 是不支持将函数 做为参数 传递的,可是实际用起来java 给咱们留了一个相似的后门。 就是回调函数了。 可是咱们要知道 他这个后门也是创建在实际传对象进去的基础上的。3d
答案是能够的。可是大家要知道 kotlin的这种特性其实也是一种语法糖,他并不能突破jvm的限制,也就是说jvm不支持函数做为参数传递,那么kotlin也是不支持的,可是kotlin 能够经过语法糖的方式,让kotlin的开发者能够认为 kotlin中能够将函数做为参数传递。cdn
咱们来举个例子:对象
看完上面的例子 咱们得出一个结论,kotlin中 函数虽然不是一种类型, 可是咱们却能够根据函数的参数和函数的返回值 来抽象出一种定义函数的方式。 就是图中我红色的注释。blog
既然有了这个基础,那么在kotlin中 咱们就能够将函数做为一个参数传递进去了。事件
既然函数a 咱们定义成了一个高阶函数,能够接受一个函数 做为参数 来调用,那咱们就看看是如何使用他吧。
到这里咱们应该得出一个结论: Kotlin中的 函数做为参数传递的时候 其实本质上传递的是一个对象。
那既然 传递的是一个对象, 也能够支持传递匿名对象的吧?其实也是能够的:
其实这俩就是对等的关系, 有了上面的基础 我再写几个例子 大家就明白了。
这个函数 你们再熟悉不过了吧,给一个view 添加一个点击事件。
本质上 咱们能够看到 其实这个setOnclickListener函数但愿获得的 是一个 参数为view 返回值为 void 的函数。
因此 咱们能够这么写:
没毛病吧?咱们给他一个 匿名的函数类型的对象 参数是view类型的,返回值是Unit 这个写法 若是上面的内容 你能看懂的话 看到这里 应该是没压力的。
而后咱们就能够用lambda 来简化咱们的写法:
v:View 表明这个匿名函数的参数类型, 而后lambda中最后一行 就表明返回值了。
由于咱们这个参数类型是一个没有返回值的 函数类型,因此这里println函数没有返回值 也没问题。
还能够更加简写一下:
你看这个写法 参数声明也省略掉了。
最后咱们再写一段代码 强化理解一下kotlin中 高阶函数与lambda的关系。
首先
咱们声明了一个函数类型的对象。 他是匿名的。 咱们想到 匿名函数不是能够用lambda 来简化吗?
而且lambda 中最后一行固定就是这个匿名函数的返回值啊
因而咱们想这样简写:
你看这里报错了,这是为啥? 其实很简单,这里编译器没法知道 你这个lambda 也就是匿名函数的参数是什么类型
你都没有声明参数的类型,你怎么能直接使用他呢? 那不是确定报错吗?
因此咱们在声明的地方标定一下 这个函数的类型(参数和返回值) 不就可使用好lambda的简写了吗?