一文理解 kotlin 中的run、with、apply、also、let的区别

在使用 kotlin 开发中,我们常常会使用到 let、 run、 with、 apply、 以及 also 这五个函数。它们的作用就是在对象的上下文中执行代码块。

在 Kotlin 中,这五个函数都可以在代码块的作用域中访问对象而无需其名称,因此它们被称为作用域函数

这五个函数主要的应用场景如下图所示,图片来源Google 工程师的推特帖子

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以看到这些函数基本上都执行同样的操作,即在一个对象上执行一个代码块。不同的是这个对象在代码块中如何使用,以及整个表达式的结果是什么。 。下面就详细介绍一下它们的区别:

函数原型上的区别

如果我们从函数原因上来看这五个作用域函数,可以讲它们分成三种,分别是:

  • 函数原型为扩展函数,这一类有 letapplyalso
  • 函数原型不是扩展函数,这一类有 with
  • 以及既有扩展函数实现方式也有非扩展函数实现方式的 run

对于函数原型为扩展函数的 letapplyalso 来说,它们必须需要一个对象才能调用,代码如下:

kotlin
 代码解读
复制代码
Person("Adam").apply { 
    age = 20          
    city = "London"
}

而对于函数原型非扩展函数的 with 来说,它可以直接被调用,代码示例如下:

kotlin
 代码解读
复制代码
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
    val firstItem = first()
    val lastItem = last()        
    println("First item: $firstItem, last item: $lastItem")
}

而对于 run,由于它有两种实现,因此上面两种方式都可以调用。

引用上下文对象的方式

runwith 以及 apply 通过关键字 this 来引用上下文对象的。 而 let 及 also 则是通过 it(默认情况下)来访问上下文对象的。最主要的区别是,在访问对象自身的属性时,this 可以省略,而 it 不可以,代码相对来说比较简洁。代码示例如下:

kotlin
 代码解读
复制代码
Person("Adam").apply { 
    age = 20     // 等同于 this.age = 20
    city = "London"
}

但是当上下文对象主要用作函数调用中的参数时,通过 it 访问上下文对象会更好。 在代码块中使用多个变量时,it 也更好一些。代码示例如下:

kotlin
 代码解读
复制代码
fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}

返回值的区别

根据返回结果的不同,五个作用域函数可以分为以下两类:

  • apply 及 also :返回上下文对象自己
  • letrun 及 with :返回代码块的结果

代码示例如下:

kotlin
 代码解读
复制代码
fun getRandomInt(): Int {
    // 返回 int 自己
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}

val numbers = mutableListOf("one", "two", "three")
// 返回代码块的结果
val countEndsWithE = numbers.run { 
    add("four")
    add("five")
    count { it.endsWith("e") }
}

小结

上文介绍了五个作用域函数在函数应用场景、函数原型、函数上下文对象、函数返回值这几个方面来比较上述作用域函数的不同点。五个作用域函数的不同点如下表所示:

函数对象引用返回值是否是扩展函数
letitLambda 表达式结果
T.run{ }thisLambda 表达式结果
run{ }-Lambda 表达式结果不是:调用无需上下文对象
withthisLambda 表达式结果不是:把上下文对象当做参数
applythis上下文对象
alsoit上下文对象

参考

作者:小墙程序员
链接:https://juejin.cn/post/7381657886802067456
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值