You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin作用域函数块是否有效内联?内联类场景疑问

Kotlin inline class与作用域函数的Lambda对象疑问解答

直接结论:你的with(arithmetic)不会创建Lambda对象

Kotlin标准库中的with函数本身是inline函数,它的定义如下:

public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

因为block参数被标记为inline,编译器会直接把Lambda里的代码内联到调用位置,不会在堆上生成任何Lambda对象实例。这完全契合你用inline class避免额外对象实例化的设计目标,不用担心作用域函数破坏你的设计。

为什么官方文档称其为Lambda表达式?

文档里的说法是从语法层面出发的——这个代码块确实符合Lambda的语法定义,但inline修饰符改变了它的编译行为:它不再是一个需要实例化的对象,而是直接被展开成调用处的代码片段。

确保作用域函数不产生对象分配的要点

  • 优先使用标准库自带的inline作用域函数:with、run、let、apply、also都是inline的,只要不手动修改它们的实现,就不会有对象创建问题。
  • 注意Lambda的捕获逻辑:如果Lambda捕获了外部的非基本类型、非inline类的变量,编译器可能会生成辅助类,但如果只是操作receiver对象(比如你的arithmetic)或者基本类型,完全不会有额外分配。

针对你的compareTo函数场景

假设你的代码类似这样:

inline class DecimalWrapper(val value: Long) : Comparable<DecimalWrapper> {
    override fun compareTo(other: DecimalWrapper): Int {
        return with(arithmetic) {
            compare(value, other.value)
        }
    }
}

这里的with代码块会被完全内联到compareTo函数中,不会产生任何额外对象,你的inline class依然能保持零额外实例化的优势。

验证方法

如果还是不确定,可以用IDE的Allocation Tracker工具,或者添加JVM参数-XX:+PrintCompilation来查看编译后的代码,确认没有意外的对象分配。

内容的提问来源于stack exchange,提问作者William Rosenbloom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 12:03:38