/** * 第 8 章 · 作用域函数 — 综合示例 * * 五兄弟:let / run / with / apply / also * * 函数 块内引用 返回 典型场景 * ──── ────── ──── ────── * let it lambda 结果 可空判空 + 转换 * run this lambda 结果 多操作 + 算结果 * with this lambda 结果 多操作 + 算结果(非扩展) * apply this 对象本身 配置对象 * also it 对象本身 日志 / 校验 / 副作用 */ class HttpRequest { var url: String = "" var method: String = "GET" var body: String? = null val headers = mutableMapOf() override fun toString() = "$method $url, headers=$headers, body=$body" fun execute() = "{\"status\":\"ok\",\"data\":\"hello\"}" } fun main() { println("=== 1. let:可空判空 + 转换 ===") val name: String? = "Alice" val len = name?.let { println(" name 不为空,长度是 ${it.length}") it.length * 2 } println(" len = $len") val nullName: String? = null val len2 = nullName?.let { it.length } ?: -1 println(" null 时返回默认: $len2") println("\n=== 2. run:多操作 + 算结果 ===") val msg = StringBuilder().run { append("Hello, ") append("Kotlin!") toString() // 返回最后一行 } println(" msg = $msg") val firstChar = "Alice".run { println(" 长度: $length") println(" 大写: ${uppercase()}") first() // 返回 'A' } println(" firstChar = $firstChar") println("\n=== 3. with:跟 run 一样,但不是扩展 ===") val sb = StringBuilder() val s = with(sb) { append("a"); append("b"); append("c") toString() } println(" s = $s") println("\n=== 4. apply:配置对象(最常用!)===") val request = HttpRequest().apply { url = "https://api.example.com/users" method = "POST" body = """{"name":"Alice"}""" headers["Content-Type"] = "application/json" headers["Authorization"] = "Bearer xxx" } println(" $request") println("\n=== 5. also:链中插入副作用 ===") val parsed = " 42 " .also { println(" 原始: '$it'") } .trim() .also { println(" trim 后: '$it'") } .toInt() .also { println(" 转 Int: $it") } println(" 最终 parsed = $parsed") println("\n=== 6. 链式组合:apply + also + run ===") val response = HttpRequest().apply { url = "https://api.example.com/v2/users" method = "GET" }.also { println(" 📤 准备发送: $it") }.execute().run { println(" 📥 收到: $this") // 解析 JSON 取 data 字段(简单提取) substringAfter("\"data\":\"").substringBefore("\"") }.also { println(" ✅ 解析: $it") } println(" response = $response") println("\n=== 7. 五兄弟同需求对比 ===") val data = "Alice" val r1 = data.let { it.length } val r2 = data.run { length } val r3 = with(data) { length } val r4 = data.apply { /* 没法返回 length,因为返回的是 data 自己 */ } val r5 = data.also { /* 同上 */ } println(" let: 返回 $r1 (Int)") println(" run: 返回 $r2 (Int)") println(" with: 返回 $r3 (Int)") println(" apply: 返回 \"$r4\" (原 String,length 被丢弃)") println(" also: 返回 \"$r5\" (原 String)") println("\n=== 8. 反模式示例 ===") val x = compute().also { println(" got: $it") } // ✅ 可读 println(" x = $x") // ❌ 反模式:单行用 also 反而绕 val y = compute() println(" got: $y") println(" y = $y") } fun compute() = 42