Kotlin第七阶段学习内容详情
Kotlin 第七阶段学习内容详情:作用域函数
本阶段目标是掌握 Kotlin 常见作用域函数:let、run、with、apply、also。它们不是新能力,而是让对象处理、空安全和初始化代码更简洁。
建议用时:2-3 天。
阶段目标
- 能理解作用域函数的共同点。
- 能区分
it和this。 - 能使用
let处理可空值。 - 能使用
apply初始化对象。 - 能使用
also做附加操作。 - 能大致理解
run和with的使用场景。 - 避免滥用作用域函数导致代码难读。
作用域函数总览
| 函数 | 对象引用 | 返回值 | 常见用途 |
|---|---|---|---|
let |
it |
Lambda 最后一行 | 空安全、局部转换 |
run |
this |
Lambda 最后一行 | 对象内计算 |
with |
this |
Lambda 最后一行 | 对已有对象批量操作 |
apply |
this |
对象本身 | 初始化对象 |
also |
it |
对象本身 | 附加操作、日志 |
初学时最先掌握 let、apply、also 即可。
第 1 天:let
1. 基础用法
fun main() {
val name = "Kotlin"
name.let {
println(it.length)
println(it.uppercase())
}
}
it 表示调用 let 的对象。
2. let 处理可空值
fun main() {
val name: String? = "Kotlin"
name?.let {
println("名字长度:${it.length}")
}
}
如果 name 为 null,let 中的代码不会执行。
3. let 返回最后一行
fun main() {
val length = "Kotlin".let {
it.length
}
println(length)
}
4. 自定义参数名
fun main() {
val name = "Kotlin"
name.let { text ->
println(text.length)
}
}
当逻辑稍复杂时,自定义参数名比 it 更清楚。
第 2 天:apply 与 also
1. apply 初始化对象
class User {
var name: String = ""
var age: Int = 0
}
fun main() {
val user = User().apply {
name = "Alice"
age = 20
}
println(user.name)
println(user.age)
}
apply 中使用 this 访问对象,通常可以省略 this。
2. apply 返回对象本身
val user = User().apply {
name = "Alice"
age = 20
}
这里 user 得到的还是 User 对象。
3. also 做附加操作
fun main() {
val numbers = mutableListOf(1, 2, 3)
.also {
println("原始数据:$it")
}
.apply {
add(4)
}
println(numbers)
}
also 常用于不改变主流程的附加操作,比如打印日志。
4. apply 和 also 对比
class User {
var name: String = ""
}
fun main() {
val user1 = User().apply {
name = "Alice"
}
val user2 = User().also {
it.name = "Bob"
}
println(user1.name)
println(user2.name)
}
apply用this。also用it。- 两者都返回对象本身。
第 3 天:run 与 with
1. run
class User(val name: String, val age: Int)
fun main() {
val user = User("Alice", 20)
val description = user.run {
"$name,今年 $age 岁"
}
println(description)
}
run 适合在对象上下文中计算一个结果。
2. with
class User(val name: String, val age: Int)
fun main() {
val user = User("Alice", 20)
val description = with(user) {
"$name,今年 $age 岁"
}
println(description)
}
with 不是扩展函数,它把对象作为参数传入。
3. 不要为了使用而使用
下面这种代码就不一定更好读:
val result = user?.let {
it.name.let { name ->
name.uppercase().let { upperName ->
"用户:$upperName"
}
}
}
更直白的写法可能更好:
val result = user?.name?.uppercase()?.let {
"用户:$it"
}
综合练习
练习 1:用 let 处理可空字符串
fun printLength(text: String?) {
text?.let {
println("长度:${it.length}")
} ?: println("文本为空")
}
fun main() {
printLength("Kotlin")
printLength(null)
}
练习 2:用 apply 初始化对象
class Book {
var title: String = ""
var author: String = ""
var price: Int = 0
}
fun main() {
val book = Book().apply {
title = "Kotlin 入门"
author = "匿名作者"
price = 59
}
println("${book.title},${book.author},${book.price}")
}
练习 3:用 also 打印调试信息
fun main() {
val result = listOf(1, 2, 3, 4, 5)
.also { println("原始数据:$it") }
.filter { it % 2 == 0 }
.also { println("筛选后:$it") }
.map { it * it }
println(result)
}
必须掌握清单
常见错误
1. 分不清返回值
val result = "Kotlin".let {
it.length
}
result 是 Int。
val result = StringBuilder().apply {
append("Kotlin")
}
result 是 StringBuilder 对象本身。
2. 过度嵌套
作用域函数嵌套太深时,可读性会变差。超过 2 层时就要警惕。
阶段复盘问题
let常用于什么场景?apply常用于什么场景?also适合做什么?it和this有什么区别?- 哪些作用域函数返回对象本身?
- 哪些作用域函数返回 Lambda 最后一行?

浙公网安备 33010602011771号