首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Kotlin系列之带接收者的Lambda

今天来看看Kotlin中关于lambda的两个函数with和apply,我们将其称为带接收者的lambda,不了解为什么会这么命令,看完下面的实例你应该就可以理解了。

注意,上面也已经说了,with和apply其实是两个函数,虽然它们看起来像是关键字。

with函数

简单使用

我们在Java中经常会写下面这样的代码:

我们上面这所以可以反复调用result的append()方法,是因为StringBuilder每次调用append()方法都会返回这个对象本身。

Kotlin中认为这样连续调用同一个对象的不同方法,每次都需要显式写出result这个对象的方法不够简介,所以提供了result方法来简化这个过程,上面的代码改造之后,在Kotlin中可以这样书写:

上面的代码虽然短小,但包含着非常丰富的信息,我们一步步分析一下:

定义的函数getRes并指定返回值为String

上面说了with是一个函数,其实它有两个参数,第一个参数是需要传入的对象,第二个参数是一个lambda表达式,根据lambda表达式的语法规则,这个lambda表达式可以写在括号外面。with函数可以让在这个lambda表达式中,所有涉及到对result对象操作的函数都可以省略调用对象result而直接调用其函数。

上面代码中我演示了在with的lambda表达式中的三种调用方法。一种是显式指定对象,一种是直接省略对象,一种是使用this调用。这里的this就表示with函数中传入的对象。

最后一行的结果就会作为这个with函数调用的返回值。

进阶使用

你看到上面的写法已经很简洁了,其实它还可以更简洁。因为在kotlin中,最后一个表达式的值,就是整个函数的返回值,同时,我们上面也说过了,在with函数的lambda表达式中,我们可以直接调用传入对象的函数,所以,上面的代码,又有了下面更加简洁的写法:

是不是看起来简洁了许多,其实就是把一些可以简化的步骤组合到了一起,为什么可以这么写,前面其实已经说过了。

可能存在的问题

上面我们的简洁写法存在一个问题,接入我们在lambda中调用的一个方法,与StringBuilder中的方法重名了,我们该怎么办呢?就像下面这样:

上面的示例代码中,我们的Sample类中已经定义了一个append方法,但是我们传入的with函数的StringBuilder中也存在一个同名的append方法。这时候,如果我们只是单纯使用append调用,只会调用StringBuilder的append方法,如果我们想调用我们自己定义的append方法,那就可以像示例代码中一样,使用this@外部类.方法名这种调用方式。

apply函数

apply函数的用法和with函数的用法几乎一模一样,唯一的差异在于,我们在使用with函数时,最终的返回结果是我们在lambda表达式中最后一个表达式的值,比如上面的例子就是toString的结果作为整个with函数的返回值。

而apply则不同,它的返回值是我们传入的对象。可能听起来有点抽象,我们这次用apply来重写上面那个例子,代码如下:

这里注意,我们不是在apply函数中传入我们的StringBuilder对象,而是直接在我们的StringBuilder对象上调用apply函数,这是因为apply是一个扩展函数,我们可以在任意对象上调用它。

然后你会注意到,我们在lambda表达式的外部调用了toString方法,正如前面所说,我们的apply函数返回的是我们传入的对象,即返回了StringBuilder对象。

apply函数的出现,成功让我们的代码在整洁的同时,保持了代码的紧凑。

其实你看到上面的例子,其实我们在Java中对于构建一个特定属性的对象,我们通常是使用Builder模式来做,但是在kotlin中,我们只需要借助apply函数就可以随意定制任意对象。

写在最后

回到一开始的疑问,为什么叫做带接收者的lambda,就是无论是我们传递给with还是apply函数的对象,都可以在lambda内部自由调用这个对象的方法,这在Java里面是没有这种能力的,这里我们传递给with或者apply的那个对象就是我们所谓的接收者

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181230G0KLO600?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券