Kotlin: run, let, apply, also, with — 何时使用?示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Kotlin: run, let, apply, also, with — 何时使用?完整解析与示例



你好,朋友!如果你正在学习 Kotlin 并希望编写简洁、优雅的代码,那么迟早会遇到五个神奇的函数:run、let、apply、also 和 with。它们是作用域函数——允许你在对象的上下文中执行代码,极大地简化了开发工作。



但问题在于:许多初学者(甚至是有经验的开发者)会混淆何时使用哪个函数。这个问题是 Stack Overflow 上最热门的问题之一,今天我们将一劳永逸地弄清楚如何避免错误。我们不仅会列出规则——还会展示来自实际项目的真实示例,你可以立即在自己的项目中使用它们。



什么是作用域函数,为什么需要它们?

作用域函数是为对象创建临时作用域的函数。在这个作用域内,你可以通过 it 或 this 访问对象。它们之间的主要区别在于如何返回结果以及如何引用上下文。



以下是一个简明的速查表,我们将用示例来填充它:

  • let — 上下文:it,返回:lambda 表达式的结果。用于非空检查和调用链。
  • run — 上下文:this,返回:lambda 表达式的结果。通用函数,常用于初始化和计算。
  • apply — 上下文:this,返回:对象本身。非常适合配置对象的属性。
  • also — 上下文:it,返回:对象本身。适合执行额外操作(日志记录、检查)。
  • with — 非扩展函数,上下文:this,返回:lambda 表达式的结果。方便对同一对象进行分组调用,而无需创建新对象。


记住主要规则:函数的选择取决于你需要返回对象还是结果,以及你希望如何引用上下文(通过 it 还是 this)。



1. let — 安全链的王者

let 是你处理可空对象时的最佳伙伴。它仅在对象不为 null 时执行代码。上下文通过 it 传递。



示例:安全转换

val name: String? = "安德烈"// 不使用 let:if (name != null) {    println("名字长度:${name.length}")}

// 使用 let(更优雅):name?.let { println("名字长度:${it.length}")}


let 也非常适合操作链。例如,当你需要将一个对象转换为另一个对象时:



val numbers = listOf(1, 2, null, 4, null, 6)val nonNullSquared = numbers    .mapNotNull { it }    .let { list ->        list.map { it * it }    }println(nonNullSquared) // [1, 4, 16, 36]


何时使用 let:

  • 空值检查(最常见的用例)。
  • 将一个值转换为另一个值。
  • 对结果执行一系列操作。


2. apply — 简洁的构造器

apply 返回对象本身,而在 lambda 内部上下文是 this。这是在使用前配置对象的理想工具。忘掉冗长的 set 代码块吧!



示例:配置 View(Android)或 data class

data class User(var name: String = "", var age: Int = 0)

val user = User().apply { name = "玛丽亚" age = 25}println(user) // User(name=玛丽亚, age=25)

// 更酷的是——配置 TextView:val textView = TextView(context).apply { text = "你好,Kotlin!" textSize = 18f setTextCo

博客

书籍推荐