Kotlin作用域函数场景选择、it与this差异及存在意义咨询
Kotlin作用域函数:关键字差异、适用场景解析
fun main() { val person = Person() person.let { it.name = "let HelloWorld" println(it.name) println("let $it") } println("let.. $person") with(person) { name = "With HelloWorld" println(this.name) println(this) } println(person) person.run { name = "Run HelloWorld" println(this.name) println(this) } println(person) person.apply { name = "apply HelloWorld" println(this.name) println(this) } println(person) person.also { it.name = "Also HelloWorld" println(it.name) println(it) } println(person) } data class Person(var name:String="", var age:Int = 0)
一、it与this的核心差异
Kotlin作用域函数的核心区分点在于上下文对象的指代逻辑:
- it:仅用于
let和also,上下文对象是以lambda参数的形式传入。你可以给它重命名(比如person.let { p -> p.name = ... }),避免变量名冲突。示例中let和also块里的it就是指代person对象。 - this:用于
with、run和apply,上下文对象作为lambda的接收者(相当于处于对象的成员方法内部)。你可以省略this直接调用对象成员(比如示例中with块里的name = "With HelloWorld"),用this明确指代上下文对象。
二、为什么需要多种作用域函数?
这些函数看似功能重叠,但核心差异在于返回值类型和上下文指代方式,对应不同的编程场景需求:
- 部分函数返回上下文对象本身(
apply、also),适合链式调用或对象初始化流程; - 部分函数返回lambda的执行结果(
let、run),适合对象转换或结果计算; - 还有的专门用于非空安全处理(
let配合?.),或简化同一对象的多成员操作(with)。
这种设计让代码语义更清晰,不同场景下选对函数能大幅提升代码可读性和简洁度。
三、各作用域函数的适用场景
1. let
- 上下文指代:
it(参数) - 返回值:lambda最后一行的执行结果
- 适用场景:
- 非空对象处理:
person?.let { ... },避免空指针异常; - 对象转换:将一个对象转换为另一种类型(比如
val nameLength = person.let { it.name.length }); - 临时作用域限制:在lambda内临时处理对象,避免污染外部作用域。
- 非空对象处理:
2. with
- 上下文指代:
this(接收者) - 返回值:lambda最后一行的执行结果
- 适用场景:
- 对同一对象执行多成员操作,无需重复书写对象名;
- 注意:
with是顶层函数,不是对象扩展函数,使用前需确保对象非空,否则会抛出空指针异常。
3. run
- 上下文指代:
this(接收者) - 返回值:lambda最后一行的执行结果
- 适用场景:
- 结合
let和with的优势:既支持非空调用(person?.run { ... }),又能像with一样省略this操作成员; - 执行多步操作并返回结果,比如初始化对象后计算某个衍生值。
- 结合
4. apply
- 上下文指代:
this(接收者) - 返回值:上下文对象本身
- 适用场景:
- 对象初始化:链式设置对象属性(比如
val person = Person().apply { name = "Alice"; age = 25 }); - 对象配置:修改已有对象后直接返回,适合链式调用(比如
person.apply { age += 1 }.let { println(it.age) })。
- 对象初始化:链式设置对象属性(比如
5. also
- 上下文指代:
it(参数) - 返回值:上下文对象本身
- 适用场景:
- 执行额外操作(比如日志打印)且不改变对象本身,适合链式调用;
- 复制对象后修改属性,同时保留原对象引用;
- 与
apply的区别:also用it指代,适合需要明确区分上下文对象和其他变量的场景,避免this歧义。
内容的提问来源于stack exchange,提问作者Ruchir
相关产品推荐
相关产品推荐

