Kotlin 作用域函数 - let 函数、run 函数

let 函数

1、基本介绍
kotlin 复制代码
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}
  1. let 是泛型扩展函数

  2. 在配合 ?. 时,将调用者 T 对象作为参数传递给 Lambda,在 Lambda 内部通过 it 访问,避免空指针

  3. 如果不配合 ?.,it 可能为 null

  4. 返回 Lambda 的执行结果 R

  5. 通过 inline 关键字内联,避免函数对象开销(让编译器直接把代码"复制粘贴"到调用处,而不是真的创建一个函数对象去调用)

2、演示
  1. 这里会执行,因为对象不为 null
kotlin 复制代码
var str: String? = "Hello, Kotlin!"

str?.let {
    println(it.length)
}

println("结束")
复制代码
# 输出结果

14
结束
  1. 这里不会执行,因为对象为 null
kotlin 复制代码
var str: String? = null

str?.let {
    println(it.length)
}

println("结束")
复制代码
# 输出结果

结束

run 函数

1、基本介绍
kotlin 复制代码
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}
kotlin 复制代码
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}
  1. run 是一个作用域函数,接收一个 lambda 表达式并在其作用域内执行

  2. run 函数分为扩展函数与非扩展函数,扩展函数对调用者 T 执行 lambda,内部通过 this 访问上下文,返回 lambda 结果,非扩展函数是独立作用域,无需上下文对象

  3. run 函数通过 inline 关键字内联,避免函数对象开销

2、演示
  1. 创建独立作用域
kotlin 复制代码
val result = run {
    val x = 10
    val y = 20
    x + y
}

println(result)
复制代码
# 输出结果

30
  1. 使用临时变量
kotlin 复制代码
val value = 100

val processed = run {
    val value = 50
    value * 2
}

println("外部 value: $value")
println("计算结果: $processed")
复制代码
# 输出结果

外部 value: 100
计算结果: 100
  1. 对象配置与计算
kotlin 复制代码
data class Person(var name: String, var age: Int)

val person = Person("Alice", 25)

val result = person.run {
    age += 1
    name = "$name Smith"
    "姓名: $name, 年龄: $age"
}

println(result)
复制代码
# 输出结果

姓名: Alice Smith, 年龄: 26
  1. 空安全检查
kotlin 复制代码
val content: String? = "Hello"

val length = content?.run {
    println("字符串: $this")
    length
} ?: 0

println(length)
复制代码
# 输出结果

字符串: Hello
5
相关推荐
weixin_440784113 小时前
【HandlerThread实现原理】
android·java·开发语言
天空'之城3 小时前
C 语言工业级通用组件手写 24:互补滤波
c语言·开发语言·互补滤波·嵌入式算法·工业级组件
leoZ2313 小时前
本地跑大模型实战(七):llama.cpp 性能调优,让推理更快更省
java·人工智能·spring·生成对抗网络·语言模型·自然语言处理·llama
XR1234567883 小时前
工厂车间无线网络方案对比:AGV漫游哪家强?
开发语言·php
傻啦嘿哟4 小时前
某短视频平台视频爬虫实战:抓取推荐流视频信息,绕过反爬的3种技巧
开发语言·爬虫·python
現実君5 小时前
【硬件进阶】AD22上位替换JLEDA教程
开发语言·php
mubei-1235 小时前
SpringDAO的用法
java·开发语言·数据库
happymagic5 小时前
java spring boot做的jar包程序,如何实现自动运行启动
java·运维·服务器·spring boot·jar
唐诺5 小时前
Android USB ADB 调试方案完全解析
android·adb·usb
格林威7 小时前
多相机微秒级对齐:硬件触发 vs PTP(IEEE 1588)方案实战对比
开发语言·人工智能·数码相机·机器学习·计算机视觉·视觉检测·机器视觉