一文弄懂 kotlin lambda与高阶函数(进阶)

1,244 阅读4分钟

阅读本文的目的?

之前有小伙伴反应 kotlin lambda与高阶函数 还是有点云里雾里的,所以特意再补上一篇,学完这篇,相信你就真正的了解了kotlin中lambda与高阶函数的 本质了,也不再害怕使用了。

java中函数能作为参数传递吗?

在java中 是不允许 将函数作为参数传递的。 这个相信多数java开发者都知道。但是java是开了一个类似的口子的。 就是回调函数。 回调函数的目的 其实就是将函数 作为一个参数传递到另外一个函数中。

类似下面的代码:

其实我们传递进去的虽然表面看起来是一个对象,但是我们使用的却是这个对象中的 方法。

所以实际上这样设计的意图就是将一个函数传递到另外一个函数里面。

语法上虽然java 是不支持将函数 作为参数 传递的,但是实际用起来java 给我们留了一个类似的后门。 就是回调函数了。 但是我们要知道 他这个后门也是建立在实际传对象进去的基础上的。

kotlin中的函数可以作为参数传递吗?

答案是可以的。但是你们要知道 kotlin的这种特性其实也是一种语法糖,他并不能突破jvm的限制,也就是说jvm不支持函数作为参数传递,那么kotlin也是不支持的,但是kotlin 可以通过语法糖的方式,让kotlin的开发者可以认为 kotlin中可以将函数作为参数传递

我们来举个例子:

看完上面的例子 我们得出一个结论,kotlin中 函数虽然不是一种类型, 但是我们却可以根据函数的参数和函数的返回值 来抽象出一种定义函数的方式。 就是图中我红色的注释。

既然有了这个基础,那么在kotlin中 我们就可以将函数作为一个参数传递进去了。

既然函数a 我们定义成了一个高阶函数,可以接受一个函数 作为参数 来调用,那我们就看看是如何使用他吧。

到这里我们应该得出一个结论: Kotlin中的 函数作为参数传递的时候 其实本质上传递的是一个对象。

那既然 传递的是一个对象, 也可以支持传递匿名对象的吧?其实也是可以的:

kotlin中的lambda 与匿名函数的关系

其实这俩就是对等的关系, 有了上面的基础 我再写几个例子 你们就明白了。

这个函数 大家再熟悉不过了吧,给一个view 添加一个点击事件。

本质上 我们可以看到 其实这个setOnclickListener函数希望得到的 是一个 参数为view 返回值为 void 的函数。

所以 我们可以这么写:

没毛病吧?我们给他一个 匿名的函数类型的对象 参数是view类型的,返回值是Unit 这个写法 如果上面的内容 你能看懂的话 看到这里 应该是没压力的。

然后我们就可以用lambda 来简化我们的写法:

v:View 代表这个匿名函数的参数类型, 然后lambda中最后一行 就代表返回值了。

因为我们这个参数类型是一个没有返回值的 函数类型,所以这里println函数没有返回值 也没问题。

还可以更加简写一下:

你看这个写法 参数声明也省略掉了。

lambda 作为一个声明语句的一部分

最后我们再写一段代码 强化理解一下kotlin中 高阶函数与lambda的关系。

首先

我们声明了一个函数类型的对象。 他是匿名的。 我们想到 匿名函数不是可以用lambda 来简化吗?

并且lambda 中最后一行固定就是这个匿名函数的返回值啊

于是我们想这样简写:

你看这里报错了,这是为啥? 其实很简单,这里编译器无法知道 你这个lambda 也就是匿名函数的参数是什么类型

你都没有声明参数的类型,你怎么能直接使用他呢? 那不是肯定报错吗?

所以我们在声明的地方标定一下 这个函数的类型(参数和返回值) 不就可以使用好lambda的简写了吗?