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
相关推荐
阿维的博客日记9 小时前
Hippo4j 线程池监控平台部署手册
java·spring boot·后端
南境十里·墨染春水10 小时前
C++ 工厂模式:从入门到进阶,彻底掌握对象创建的艺术
开发语言·c++·算法
C+++Python11 小时前
详细介绍一下Java泛型的通配符
java·windows·python
开维游戏引擎11 小时前
AI自动生成游戏时,deepseek和mimo对比
android·游戏·语言模型·游戏引擎·ai编程
JosieBook12 小时前
【数据库】时序预测能力的分级进化:TimechoAI如何让每一类用户都能精准预见未来
java·开发语言·数据库
加号312 小时前
【C#】 文件与目录管理:创建、删除操作的技术解析
开发语言·c#
diving deep12 小时前
脚本速览-python
开发语言·python
一生了无挂13 小时前
Java处理JSON技巧教学(从基础到高阶实战全覆盖)
java·开发语言·json
李白的天不白13 小时前
使用 SmartAdmin 进行前后端开发
java·前端
swordbob13 小时前
Spring 单例 Bean 是线程安全的吗?
java·开发语言