⚡Kotlin 五大神器完全解析:let、with、run、apply、also 一次搞懂,面试官都笑了!

🌟 前言

Kotlin 里有五个"看似相似、实则各有门派"的函数:

letwithrunapplyalso

它们是 Kotlin 官方定义的"标准函数(Standard Functions)",

被誉为:

✨"让代码更简洁的五大法术"。

可是在面试中,它们也是让人最头疼的考点之一:

💬"run 和 apply 有什么区别?"

💬"什么时候用 letalso 更合适?"

💬"with 为什么几乎不推荐用了?"

今天,我们不光要讲清楚每个函数的 定义 + 场景 + 区别

还要让你最后能用一句话轻松记住它们!


🧩 一、let ------ 最常用的空安全与链式利器

🔹 定义

kotlin 复制代码
inline fun <T, R> T.let(block: (T) -> R): R

👉 把当前对象(this)作为参数 it 传入 block 中执行,返回 block 的结果。

🔹 使用场景 1:空安全

bash 复制代码
user?.let {
    println("User name: ${it.name}")
}

只有在 user 非空时才执行,防止空指针异常(NullPointerException)。

🔹 使用场景 2:链式操作

scss 复制代码
val result = text?.let { it.trim() }?.let { it.uppercase() }

可连续调用,简洁优雅。

🔹 使用场景 3:临时作用域

bash 复制代码
val length = "Kotlin".let {
    println("String is: $it")
    it.length
}

减少全局变量污染。

✅ 一句话理解: let 用于安全调用或链式处理,返回最后一行表达式的结果。


⚙️ 二、with ------ 对同一对象执行多操作的老派绅士

🔹 定义

kotlin 复制代码
inline fun <T, R> with(receiver: T, block: T.() -> R): R

with 是一个普通函数,不是扩展函数。

需要把对象作为参数传入。

🔹 使用场景:连续操作一个对象

ini 复制代码
with(paint) {
    color = Color.RED
    style = Paint.Style.FILL
    strokeWidth = 3f
}

🔹 DSL 风格构建

scss 复制代码
val text = with(StringBuilder()) {
    append("Hello, ")
    append("Kotlin!")
    toString()
}

✅ 一句话理解: with 适合对同一对象进行多步操作,并返回结果。


⚡ 三、run ------ 既能执行又能返回的多面手

🔹 定义

kotlin 复制代码
inline fun <T, R> T.run(block: T.() -> R): R

run 的语义是"执行一段代码,并返回结果"。

常用于"初始化 + 返回值"。

🔹 使用场景 1:对象初始化 + 返回结果

scss 复制代码
val config = Config().run {
    setMode("Dark")
    setSize(1080, 1920)
    this // 返回整个对象
}

🔹 使用场景 2:空安全执行逻辑

arduino 复制代码
val len = text?.run {
    println("Length: $length")
    length
} ?: 0

✅ 一句话理解: run 在对象上下文中执行逻辑,并返回表达式结果。


🔮 四、apply ------ 对象初始化的终极神器

🔹 定义

kotlin 复制代码
inline fun <T> T.apply(block: T.() -> Unit): T

applyrun 的区别是:返回对象本身

🔹 使用场景:创建并配置对象

scss 复制代码
val dialog = AlertDialog.Builder(context).apply {
    setTitle("Warning")
    setMessage("Are you sure?")
    setPositiveButton("Yes", null)
}.create()

🔹 连贯初始化

scss 复制代码
val json = JSONObject().apply {
    put("name", "Kotlin")
    put("version", "1.9")
}.toString()

✅ 一句话理解: apply 用于初始化对象,返回对象自身。


💡 五、also ------ 调试与副作用专用的隐形帮手

🔹 定义

kotlin 复制代码
inline fun <T> T.also(block: (T) -> Unit): T

apply 类似,但 also 使用 it 而不是 this

🔹 使用场景 1:打印调试

kotlin 复制代码
val user = User("Tom", 18).also {
    println("Created user: $it")
}

🔹 使用场景 2:链式调用插入副作用

scss 复制代码
val list = mutableListOf(1, 2, 3)
    .also { println("Before add: $it") }
    .apply { add(4) }
    .also { println("After add: $it") }

✅ 一句话理解: also 用于链式副作用(打印、调试、记录),返回对象自身。


🧠 六、五大函数对比总结表

函数 是否扩展函数 作用域对象 Lambda 参数 返回值 常用场景
let it 参数 最后一行结果 空安全、链式调用
with this 最后一行结果 对象多属性操作
run this 最后一行结果 执行逻辑 + 返回值
apply this 对象自身 初始化配置对象
also it 参数 对象自身 副作用(日志、调试)

💬 七、面试高频问题

Q1:applyrun 有什么区别?

apply 返回对象本身,常用于初始化;run 返回表达式结果,常用于执行逻辑。


Q2:letalso 都有 it,怎么区分?

let 用于处理结果或转换数据;also 用于插入副作用(打印、记录),不改变结果。


Q3:with 现在还推荐用吗?

Kotlin 官方推荐用 run 或 apply 代替,

因为 with 不是扩展函数,链式调用不方便。


🚀 八、实战对比:优雅的 Kotlin 写法

原始写法:

ini 复制代码
if (user != null) {
    user.name = "Tom"
    user.save()
}

Kotlin 写法:

ini 复制代码
user?.apply {
    name = "Tom"
    save()
}

更安全、更简洁、更 Kotlin。


🧩 九、一句话记住它们!

🪄 口诀:

let 看结果,

with 管上下文,

run 执逻辑要返回,

apply 初始化最方便,

also 插副作用不改变。


🧠 总结

Kotlin 的这五个函数并不是炫技的糖衣,

它们是让你的代码表达更自然、结构更安全的核心。

理解它们的语义 + 返回值 + 使用场景

你不仅能写出更优雅的 Kotlin,还能在面试中轻松应对所有关于它们的问题。

一句话总结:

五大函数不同在「返回值」与「使用场景」,

记住口诀,写出 Kotlin 的优雅与效率! ✅


相关推荐
木易 士心4 小时前
Spring Boot + Kotlin + Gradle 构建现代化后端应用
spring·kotlin
QmDeve4 小时前
Android 使用液态玻璃(LiquidGlass)效果,真实的折射和色散效果
android·github
xhbh6664 小时前
【实战总结】MySQL日志文件位置大全:附查找脚本和权限解决方案
android·adb
Digitally5 小时前
6 种无误的方法:如何备份和恢复华为手机
android
ideaout技术团队6 小时前
android集成react native组件踩坑笔记(Activity局部展示RN的组件)
android·javascript·笔记·react native·react.js
shaominjin1236 小时前
单例模式:设计模式中的“独一无二“之道
android·单例模式·设计模式
千里马学框架7 小时前
windows系统上aosp15上winscope离线html如何使用?
android·windows·html·framework·安卓窗口系统·winscope
码住懒羊羊7 小时前
【C++】模板进阶 | 继承
android·java·c++
urkay-7 小时前
Android 线程详解
android·java·kotlin·iphone·androidx