Kotlin Academy · 课时

also:不改变接收者的副作用操作

使用 also 进行日志记录、调试和仅产生副作用的操作。

第 3 / 4 课14 个步骤

also:不改变接收者的副作用操作 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

also 概览

also 会在接收者作为 it 的情况下运行代码块,并原样返回接收者。它非常适合执行副作用操作,例如日志记录、调试和验证,同时不会中断链式调用。

also 基础知识

also { ... } 会执行副作用操作,并返回相同的值,因此调用可以自然地继续进行。

fun main() {
    val nums = listOf(1, 2, 3, 4)
        .also { println("input: $it") }
        .filter { it % 2 == 0 }
        .also { println("filtered: $it") }
    println(nums)
}

使用 also 进行日志记录

在链式流程中途添加日志语句,同时不会中断流程。

fun main() {
    val processed = "  Hello, Kotlin!  "
        .also { println("raw: '$it'") }
        .trim()
        .also { println("trimmed: '$it'") }
        .uppercase()
    println(processed)
}

使用 also 进行调试

重构期间,可以使用 also 检查中间状态,之后移除它也不会改变链式调用。

fun main() {
    val sum = (1..5).toList()
        .also { println("list: $it") }
        .sum()
        .also { println("sum: $it") }
    println("final: $sum")
}

also 与 apply

apply 使用 this(更适合赋值)。also 使用 it(更适合显式引用和执行副作用操作)。

class Counter {
    var value: Int = 0
}
fun main() {
    val c = Counter().apply { value = 10 } // uses this implicitly
    val d = Counter().also { it.value = 10 } // uses it explicitly
    println("${c.value} / ${d.value}")
}

使用 also 执行初始化副作用

如果您需要在创建对象期间对它执行某项操作,而不是设置属性,这种方式就很有用。

class Repository {
    val cache = mutableMapOf<String, String>()
    fun init() = println("Repository initialized")
}
fun main() {
    val r = Repository().also { it.init() }
    r.cache["key"] = "value"
    println(r.cache)
}

also 返回原始值

接收者会原样传递下去,因此很容易继续进行链式调用。

fun main() {
    val len = "Hello".also { println("got: $it") }.length
    println(len) // 5
}

使用 also 进行验证

在链式调用中途运行断言。

fun main() {
    val n = listOf(1, 2, 3, 4)
        .filter { it > 0 }
        .also { require(it.isNotEmpty()) { "must have positives" } }
        .sum()
    println(n)
}

组合使用 also 与 let

在同一个链式流程中,使用 also 执行副作用操作,使用 let 进行转换。

fun main() {
    val raw: String? = "  42  "
    val n = raw
        ?.also { println("raw: '$it'") }
        ?.let { it.trim().toIntOrNull() }
        ?.also { println("parsed: $it") }
    println(n)
}

使用 also 添加到集合

以内联方式将构造出的对象添加到列表中。

class User(val name: String)
fun main() {
    val users = mutableListOf<User>()
    val ada = User("Ada").also { users.add(it) }
    val ben = User("Ben").also { users.add(it) }
    println(users.map { it.name })
}

何时使用 also

当您需要执行副作用操作(记录日志、验证或注册),但又希望原始值继续传递时,请使用 also。

fun main() {
    val total = listOf(10, 20, 30, 40, 50)
        .also { println("count: ${it.size}") }
        .filter { it >= 30 }
        .also { println("kept: $it") }
        .sum()
    println("total: $total")
}

反模式:使用 also 重新赋值

当您实际需要进行转换时,不要使用 also,这正是 let/run 的用途。

fun main() {
    val name = "ada"
    // BAD: also returns receiver, so upper is wrong
    // val upper = name.also { it.uppercase() } // upper == "ada"
    val upper = name.let { it.uppercase() }
    println(upper) // ADA
}

快速检查

also 执行代码块后会返回什么值?

回顾

also 使用 it 运行副作用代码块,并返回接收者。需要查看值但不改变它时,可以用它进行日志记录、调试、验证和注册。需要进行转换时,请改用 let 或 run。

免费开始

用 AI 导师学习 Kotlin — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
51
课程
203

常见问题解答

「also:不改变接收者的副作用操作」课时是免费的吗?

是的 — 「also:不改变接收者的副作用操作」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「also:不改变接收者的副作用操作」这节课中我会学到什么?

使用 also 进行日志记录、调试和仅产生副作用的操作。 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「also:不改变接收者的副作用操作」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. apply 与 with:配置并返回
  2. let 与 run:转换与作用域
  3. also:不改变接收者的副作用操作
  4. 选择合适的作用域函数:决策指南
← 返回 Kotlin Academy