run、with、apply、also、let
这五个函数作用基本一致,就是运行闭包中的代码并返回值,只有在用法上有一些区别。
用法示例:
现有Person
类定义如下:
class Person(
var name: String = "bob",
var age: Int = 15,
var sex: Char = '男',
var height: Int = 194,
var weight: Int = 88
)
以下代码示意了这五个内置函数的用法
val human = Person()
val result1 = human.run {
name = "alice"
name // 返回值
}
val result2 = with(human) {
age = 12
age // 返回值
}
val result3 = human.let {
it.sex = '女'
it.sex // 返回值
}
val result4 = human.also {
it.height = 166
it.height // 此句无效,将返回原对象
}
val result5 = human.apply {
weight = 55
weight // 此句无效,将返回原对象
}
println("result1: $result1\n" +
"result2: $result2\n" +
"result3: $result3\n" +
"result4: $result4\n" +
"result5: $result5")
打印结果:
result1: alice
result2: 12
result3: 女
result4: Person@133314b
result5: Person@133314b
在闭包内可以直接使用这个对象的属性或者方法(即this
指代这个对象),称这个对象为接收器。
如果闭包内的it
(也可以自定义)指代这个对象,那么它就作为参数。
以下表格列举了除了with
以外的4个函数:
原对象角色 | 返回值 | |
---|---|---|
run | 接收器 | 闭包返回值 |
apply | 接收器 | 原对象 |
also | 参数 | 原对象 |
let | 参数 | 闭包返回值 |
with
和run
基本等价,唯一的区别是run
是扩展函数,with
是独立的函数。
// 这两种写法等价
with(obj) { /* ...*/ }
obj.run { /* ...*/ }
repeat(n, block)
重复n次执行代码块。相当于fori
,实际上实现也是用的fori。
// 以下二者等价
repeat(100) { println("hello world") }
for(i in 1..100) { println("hello world") }