Kotlin 2.2~2.4 更新速览与 2.5+ 展望
📌 本文关注 Kotlin 2.2 ~ 2.4 版本的新语法与新特性,并尝试通过 KEEP 探索 2.5+ 可能引入的重大特性。
飞书文档阅读体验更佳:Lark: Kotlin 2.2~2.4 更新速览与 2.5+ 展望
之前的 2.0~2.1 总结文档:Kotlin 2.0 更新速览与 2.1、2.2+ 展望
官方特性追踪页面:kotlinlang.org/docs/kotlin…
2.2
Released: June 23, 2025
官方完整更新:kotlinlang.org/docs/whatsn…
2.2 是一个承上启下的版本,将 2.1 引入的多个预览特性推进到 Stable,同时引入了两个重大的新预览特性:Context Parameters 和 Context-sensitive Resolution。
Stable 特性
Guard Conditions(when 守卫条件)
在 2.1 中引入预览,2.2 正式 Stable。在 when 的分支中可以使用 if 添加额外条件:
github.com/Kotlin/KEEP… github.com/Kotlin/KEEP… youtrack.jetbrains.com/issue/KT-13…
我们定义如下的 Status 和 Problem,这是一种很常见的网络错误的处理方式:
enum class Problem {
CONNECTION, AUTHENTICATION, UNKNOWN
}
sealed interface Status {
data object Loading : Statusdataclass Error(val problem: Problem, val isCritical: Boolean) : Status
data class Ok(val info: List<String>) : Status
}
在新的方式下我们能这么写:
fun render(status: Status): String = when (status) {
Status.Loading -> "loading" // 能省略 is
is Status.Ok if status.info.isEmpty() -> "no data" // 还能跟额外条件
is Status.Ok -> status.info.joinToString() // 也可以不省略
is Status.Error if status.problem == Problem.CONNECTION ->
"problems with connection"
is Status.Error if status.problem == Problem.AUTHENTICATION -> // 相同主条件,不同附加条件
"could not be authenticated"
else -> "unknown problem"
}
之所以这么做的原因是因为过去条件表达式只能写一个,在过去上面的一大坨要这么写,非常冗余
fun render(status: Status): String = when (status) {
status is Status.Loading -> "loading"
status is Status.Ok && status.info.isEmpty() -> "no data"
status is Status.Ok -> status.info.joinToString()
status is Status.Error && status.problem == Problem.CONNECTION ->
"problems with connection"
status is Status.Error && status.problem == Problem.AUTHENTICATION ->
"could not be authenticated"
else -> "unknown problem"
}
Non-local break and continue
在 2.1 中引入预览,2.2 正式 Stable。对于原地调用(inline)的 lambda,现在可以直接使用 break 和 continue:
fun processList(elements: List<Int>) {
for (element in elements) {
// 以前在 lambda 中 break/continue 会报错
elements.forEach {
if (it == 0) break // 跳出 for 循环
if (it < 0) continue // 继续 for 循环下一轮
println(it)
}
}
}
Multi-dollar Interpolation(多美元符号插值)
在 2.1 中引入预览,2.2 正式 Stable。使用 $$ 前缀(或更多 $)可以在字符串中自由使用 $ 符号,非常适合模板引擎、正则表达式等场景:
val KClass<*>.jsonSchema: String get() = $$"""
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/$${simpleName}.schema.json",
"$ref": "https://example.com/$${simpleName}.json"
}
"""
在 $$ 模式下,只有 $${ } 才会触发变量插值,单个 $ 被当作纯文本处理。
新语法预览
Context Parameters(上下文参数)
这是一个重大新特性,用于替代之前实验性的 Context Receivers。函数和属性可以声明隐式的上下文依赖,调用时由编译器自动从上下文中解析。
核心区别:Context Parameters 不是 receiver,必须通过名字来访问成员,不会污染作用域。
// 声明 context parameter
context(users: UserService)
fun outputMessage(message: String) {
users.log("Log: $message") // 通过名字 users 访问
}
// 属性也可以
context(users: UserService)
val firstUser: String
get() = users.findUserById(1)
// 使用 _ 可以不命名,仅用于上下文传递
context(_: UserService)
fun logWelcome() {
outputMessage("Welcome!") // 自动解析上下文
}
通过 context() 函数引入上下文:
fun main() {
val userService = RealUserService()
context(userService) {
outputMessage("Hello!") // userService 被自动传入
println(firstUser)
}
}
函数类型也可以带有 context:
// 以下类型等价
context(Logger, User)() -> Int
context(Logger) User .() -> Int
(Logger, User) -> Int
启用方式:-Xcontext-parameters
2.4 中 Context Parameters 已正式 Stable!
Context-sensitive Resolution(上下文敏感解析)
在过去,即使编译器可以推断出类型,我们仍然必须写全名。现在,在能推断出类型的位置,可以省略限定名:
enum class Problem {
CONNECTION, AUTHENTICATION, DATABASE, UNKNOWN
}
// Before: 必须写 Problem.CONNECTION
fun message(problem: Problem): String = when (problem) {
Problem.CONNECTION -> "connection"
Problem.AUTHENTICATION -> "authentication"
Problem.DATABASE -> "database"
Problem.UNKNOWN -> "unknown"
}
// After: 省略 Problem.
fun message(problem: Problem): String = when (problem) {
CONNECTION -> "connection"
AUTHENTICATION -> "authentication"
DATABASE -> "database"
UNKNOWN -> "unknown"
}
不仅限于 enum,sealed class 的子类在 is 检查中也可以省略:
sealed interface Either<out E, out A> {
data class Left<out E>(val error: E) : Either<E, Nothing>
data class Right<out A>(val value: A) : Either<Nothing, A>
}
fun <E, A> Either<E, A>.getOrElse(default: A) = when (this) {
is Left -> default // 省略 Either.
is Right -> value
}
此外还支持 companion object 的属性解析,例如 Color.WHITE 可以在上下文明确时直接写 WHITE。
适用场景包括:when 表达式的 subject、显式返回类型、声明的变量类型、is/as 检查、参数类型等。
启用方式:-Xcontext-sensitive-resolution
Nested Type Aliases(嵌套类型别名)
之前 typealias 只能写在顶层,现在可以在类内部声明:
class Dijkstra {
typealias VisitedNodes = Set<Node>
private fun step(visited: VisitedNodes, ...) = ...
}
2.2 中为 Beta,2.3 中正式 Stable。
@all 注解目标
简化属性注解,将注解应用到所有相关目标(param、property、field、get、setparam),写过注解处理的都知道这玩意有多累
data class User(
val username: String,
// 一个 @all 替代多个 @param:/@field:/@get:/@property:
@all:Email val email: String,
)
@JvmExposeBoxed
为 inline value class 生成 Java 可调用的 boxed 变体,解决 Java 无法使用 inline class 构造函数的问题:
@JvmExposeBoxed
@JvmInline
value class MyInt(val value: Int)
// Java 中现在可以:
MyInt input = new MyInt(5);
2.3
Released: December 16, 2025
官方完整更新:kotlinlang.org/docs/whatsn…
2.3 专注于特性稳定化,并引入了多个重要的实验性特性:Explicit Backing Fields、Unused Return Value Checker 和 * Version Overloading*。
Explicit Backing Fields(显式幕后字段)
(虽说是官方写的 2.3 进入实验性,事实上我在 2.0 就发现有这个特性了) github.com/Kotlin/KEEP…
这个特性解决了 Android/Compose 开发中最常见的样板代码模式之一——backing property pattern(_property/property 双属性模式)。
// Before: 需要两个属性
class MyViewModel : ViewModel() {
private val _city = MutableStateFlow("")
val city: StateFlow<String> get() = _city
fun updateCity(newCity: String) {
_city.value = newCity
}
}
// After: 一个属性搞定
class MyViewModel : ViewModel() {
val city: StateFlow<String>
field = MutableStateFlow("")
fun updateCity(newCity: String) {
// 在声明作用域内,编译器自动 smart cast 到 MutableStateFlow
city.value = newCity
}
}
关键点:
field关键字声明幕后字段的类型和初始值- 在类内部(声明作用域)自动 smart cast 到字段类型
- 外部访问时只能看到属性的公开类型
- 属性必须是
val,不能有自定义 getter
启用方式:-Xexplicit-backing-fields
Unused Return Value Checker(未使用返回值检查器)
新的编译器检查器,可以在返回值被忽略时发出警告。通过 @MustUseReturnValues 标注需要检查的范围:
@MustUseReturnValues
class Greeter {
fun greet(name: String): String = "Hello, $name"
}
fun main() {
val greeter = Greeter()
greeter.greet("World") // ⚠️ 警告:返回值被忽略
// 使用 val _ 显式忽略
val _ = greeter.greet("World") // OK,不警告
}
可以用 @IgnorableReturnValue 标注那些返回值可以忽略的函数(如 MutableList.add)。
实际应用场景:实际应用场景:这个特性对响应式框架(Flow、RxJava 等)特别有价值。在这些框架中,操作的返回值如果被忽略,会很容易出
bug(比如 disposable 未解除)——开发者忘记了继续链式调用或收集结果。
kotlin-result 库已经采用了该特性:库以 full 模式启用检查器,然后仅对
onSuccess/onFailure 等纯副作用函数标注 @IgnorableReturnValue,消费者即可在自己的构建中开启检查来捕获意外丢弃的
Result。
启用方式:-Xreturn-value-checker=check(标注的范围)或 -Xreturn-value-checker=full(全项目)
Version Overloading(版本重载 KEEP-0431)
2.3 中引入的实验性特性,引入 @IntroducedAt 注解,自动为新增的可选参数生成二进制兼容的隐藏重载。
这个特性能解决 Compose 的版本兼容痛点。使得给 Button、Text 等 Composable 函数添加新参数时,不再需要手动维护旧签名的 hidden deprecated 重载保证二进制兼容性,从而导致源码中充斥着大量无意义的重复代码:
// Before: 每次加参数都要手动维护旧重载
@Deprecated("Deprecated", level = DeprecationLevel.HIDDEN)
fun Button(label: String = "", color: Color = DefaultColor, onClick: () -> Unit) =
Button(label, color, DefaultBorderColor, DefaultBorderStyle, 1, onClick)
// v1.1: 又多一个旧重载...
@Deprecated("Deprecated", level = DeprecationLevel.HIDDEN)
fun Button(
label: String = "", color: Color = DefaultColor,
borderColor: Color = DefaultBorderColor, onClick: () -> Unit
) = ...
// After: 一个注解搞定
fun Button(
label: String = "",
color: Color = DefaultColor,
@IntroducedAt("1.1") borderColor: Color = DefaultBorderColor,
@IntroducedAt("1.2") borderStyle: Style = DefaultBorderStyle,
@IntroducedAt("1.2") borderWidth: Int = 1,
onClick: () -> Unit,
) { /* body */
}
// 编译器自动生成 v1.0 和 v1.1 的隐藏重载
对 data class 的构造函数同样有效,还会自动生成对应版本的 .copy() 重载。
启用方式:@OptIn(ExperimentalVersionOverloading::class)
Context-sensitive Resolution 改进
在 2.3 中,上下文敏感解析继续改进:
- sealed class 和封闭父类型现在也被纳入上下文搜索范围
- 当类型操作符和相等性判断与上下文敏感解析冲突时,编译器会给出警告
其他稳定特性
- Nested Type Aliases 从 Beta 升级为 Stable
- Data-flow-based exhaustiveness checks 正式 Stable:基于数据流的
when穷尽性检查更智能
2.3.20
Released: March 16, 2026
官方完整更新:kotlinlang.org/docs/whatsn…
Name-based Destructuring(基于名称的解构)
这是一个重新设计解构声明的重大提案。过去的解构基于位置(componentN()),容易导致语义混淆:
data class User(val username: String, val email: String)
// 基于位置的解构:变量名和实际值不匹配!
val (email, username) = User("alice", "alice@example.com")
// email = "alice"(其实是 username),username = "alice@example.com"(其实是 email)
新的基于名称的解构通过属性名匹配,避免这个问题:
// 新语法:显式名称解构
(val mail = email, val name = username) = User("alice", "alice@example.com")
// mail = "alice@example.com",name = "alice" ✅ 正确!
// 新的位置解构语法使用方括号
val [first, second] = user // 位置解构
编译器提供三种模式:
only-syntax:仅启用新语法name-mismatch:当位置解构的变量名不匹配属性名时警告complete:圆括号默认名称解构,方括号用于位置解构
启用方式:-Xname-based-destructuring=only-syntax
最终目标是让 val (x, y) = expr 默认变为名称解构,val [x, y] = expr 用于位置解构。
Context Parameters 重载解析变更
仅靠 context 不同的重载现在会产生歧义。这促使了 2.4 中显式 context 参数特性的诞生。
2.4
2.4.0-Beta1 Released: March 31, 2026
官方完整更新:kotlinlang.org/docs/whatsn…
Context Parameters 正式 Stable!
这是 2.4 最重要的里程碑。Context Parameters 从 2.2 的 Preview 正式毕业为 Stable 特性(callable references 除外),不再需要 opt-in,详见 2.2 部分对这一特性的描述
Explicit Context Arguments(显式上下文参数)
为了解决 2.3.20 中 context parameter 重载歧义的问题,2.4 引入了在调用点显式传递 context 参数的能力:
class EmailSender
class SmsSender
context(emailSender: EmailSender)
fun sendNotification() {
println("Sent email notification")
}
context(smsSender: SmsSender)
fun sendNotification() {
println("Sent SMS notification")
}
context(defaultEmailSender: EmailSender, defaultSmsSender: SmsSender)
fun notifyUser() {
// 通过名字选择使用哪个 context 的 overload
sendNotification(emailSender = defaultEmailSender) // → email
sendNotification(smsSender = defaultSmsSender) // → sms
}
启用方式:-Xexplicit-context-arguments
Collection Literals(集合字面量 KEEP-0416)
进度分析:提案文本完整,有工作原型分支,性能基准测试已完成。Discussion 从 2025 年 3 月活跃至 2026 年 2 月。可能在 2.5 Preview。
引入 [...] 语法创建集合:
// Before
val list = listOf(1, 2, 3)
if (readlnOrNull() in listOf("y", "Y", "yes", "Yes", null)) {
...
}
// After
val list = [1, 2, 3] // List<Int>
val set: Set<Int> = [1, 2, 3]
if (readlnOrNull() in ["y", "Y", "yes", "Yes", null]) {
...
}
关键设计:
- 根据期望类型多态:默认推断
List,显式声明Set<Int>时推断为 Set - 通过
companion object的operator fun of支持自定义类型 - 未来可能扩展支持 Map 字面量:
["key": 1]
class MyList<T> {
companion object {
operator fun <T> of(vararg elements: T): MyList<T> = TODO()
}
}
val myList: MyList<Int> = [1, 2, 3] // 等价于 MyList.of(1, 2, 3)
除了更简洁的语法外,编译器对 x in [a, b, c] 模式有特殊优化——不实际创建集合,而是展开为
x == a || x == b || x == c,消除不必要的分配。这让集合字面量不仅更美观,在 in 检查场景下性能也更好。
值得注意的是,该提案特意选择了 operator fun of 命名以与 Java 的 List.of() 等工厂方法对齐,确保 Java 生态的 of
方法可以直接作为集合字面量的后端。
其他更新
- Annotation use-site targets 特性正式 Stable(
@all元目标、新的默认规则) - Swift Package Import:Kotlin Multiplatform 项目可以在 Gradle 中直接声明 Swift 包依赖
- 支持 Java 26 字节码生成
- Annotations in metadata 默认启用
2.5+ 展望
以下特性通过 KEEP 提案探索,我们根据 GitHub PR 信号、KEEP 讨论热度、官方 Roadmap(2026年2月更新)以及提案成熟度,将其分为不同的"预期落地时间"层级。 这些预测并不代表官方承诺,是我个人猜的。
Kotlin 2.4.0 预计 2026 年 6~7 月发布,2.4.20 预计 9 月发布。
有实现信号,很可能 2.5 落地
Companion Blocks and Extensions(Companion 块与扩展 KEEP-0449/467)
该提案是早期 Statics 提案(KEEP-0427)的最新迭代,解决了 Kotlin 中 companion object 的几个长期痛点:
data class Vector(val x: Double, val y: Double) {
// companion 块:不创建 companion object 实例,编译为真正的 static
companion {
val Zero: Vector get() = Vector(0.0, 0.0)
}
}
// companion 扩展:即使类没有 companion object 也可以定义!
companion val Vector.UnitX get() = Vector(1.0, 0.0)
// 对 Java 类也能用
companion fun String.isEmail(): Boolean = contains("@")
核心优势:
companion { }块中的成员编译为平台静态成员,无 companion object 分配开销companion扩展可以定义在任何类上,包括没有 companion object 的类和 Java 类- companion 块和扩展在解析中优先于 companion object
- “即使没有 companion object” 也可以扩展这一特性,能够有效帮助注入“kotlin-inject” 这样的依赖注入框架绑定到它们的实现类
// 过去 val appComponent = AppComponent::class.create() // 现在 val appComponent = AppComponent.create()
Power-Assert Explanation(KEEP-0458)
落地信号:KEEP 中状态标注为 "Prototype available in 2.4.0-Beta2"。
Power-assert 从一个编译器插件升级为语言级支持,引入 @PowerAssert 注解和 CallExplanation 数据结构,可以在任意函数(不仅仅是
assert)上获取调用点的详细信息。
可能在 2.5 Preview
Rich Errors / 联合类型(KEEP-0441)
这可能是 Kotlin 未来最令人期待的新特性。它引入了受限联合类型用于类型安全的错误处理,本质上是 T? 思想的扩展。
进度分析:讨论非常活跃,完整设计 KEEP 尚未定型。社区强烈要求引入类似 Rust ? 或 Swift try 的错误传播操作符。最早可能在 2.5 Preview,更可能在 2.6。
核心语法
error object NotFound
error class NetworkError(val code: Int)
fun loadUser(id: String): User | NotFound | NetworkError
error 是新的关键字,定义错误类型。错误类型形成独立于 Any 的平行层级,不能有父类、父接口或泛型参数。
错误处理与操作符
when (val user = loadUser("123")) {
is User -> println("Hello, ${user.name}")
is NotFound -> println("User not found!")
is NetworkError -> println("Network error: ${user.code}")
}
与可空类型类似,复用 ?. 和 !! 操作符(也可能未来采用 !.):
fun bar(value: Int | MyError) {
value?.giveString() // 类型是 String | MyError(错误传播)
value!! // 如果是错误,抛出 KotlinErrorException
}
// 链式调用自动累积错误类型
error object NoData
error object FeatureDisabled
fun loadModel(): Model | NoData
fun Model.computeTask(): Task | FeatureDisabled
val task = loadModel()?.computeTask()
// task 的类型是 Task | NoData | FeatureDisabled
与过去的对比
// Before: 使用 Any? 和 @Suppress 强转
inline fun <T> Sequence<T>.last(predicate: (T) -> Boolean): T {
var last: Any? = NotFound
for (element in this) {
if (predicate(element)) last = element
}
if (last == NotFound) throw NoSuchElementException()
@Suppress("UNCHECKED_CAST")
return last as T
}
// After: 类型安全,无需强转
inline fun <T> Sequence<T>.last(predicate: (T) -> Boolean): T {
error object NotFound // 局部错误对象
var last: T | NotFound = NotFound
for (element in this) {
if (predicate(element)) last = element
}
if (last == NotFound) throw NoSuchElementException()
return last // smart-cast 到 T
}
typealias 组合错误 & 标准库迁移设想
typealias UserFetchError = NotFound | PermissionDenied
fun fetchUser(): User | UserFetchError
// 标准库迁移
fun IntArray.max(): Int | NoSuchElement // maxOrNull -> max
fun <T> awaitSingle(): T | NoSuchElement // awaitSingleOrNull -> awaitSingle
Rich Errors 与前面提到的 Unused Return Value Checker 是天然搭档——配合 must-use
语义,编译器可以确保错误联合的返回值不会被忽略。对于目前使用 Arrow Either、kotlin.Result 或自定义 Result 类型的项目,Rich
Errors 将提供更轻量、无包装的原生替代方案。
Better Immutability / Value Classes 2.0(KEEP-0453/0454)
2026 年 2 月发布两份 KEEP,MFVC 设计相当完整。依赖 Name-based Destructuring(已 Preview)和 More Specific Equals(KEEP-0456,进行中)。可能在 2.5 作为 Experimental。
1. Multi-field Value Classes(多字段值类 / MFVC)
value class Complex(val re: Double, val im: Double)
value class Color(val r: Int, val g: Int, val b: Int, val a: Int = 255)
特性:浅不可变、无身份、结构相等,自动生成 equals/hashCode/toString,支持 value object(零属性值对象),支持抽象值类,不支持
open 值类,不自动生成 componentN(配合名称解构使用)。
2. Ergonomic Updates —— copy var
// copy 阶梯地狱
val updated = user.copy(address = user.address.copy(zipCode = user.address.zipCode.copy(code = "1079MZ")))
// copy var 语义(设想中)
value class User(copy var name: String, copy var address: Address)
var user = User(...)
user.name = "New Name" // 实际上是 user = user.copy(name = "New Name")
user.address.zipCode.code = "1079MZ" // 递归 copy
3. Deep Immutability(深层不可变性)
编译器保证整个对象图完全不可变。这对 Compose Stability 分析、并发安全、缓存至关重要。这部分将在 MFVC 基础之上后续推进。
对 Compose 的价值:MFVC 的主要属性(val、结构相等、无身份)天然满足 Compose 的 "stable"
定义。更重要的是,由于其主构造属性是编译器保证的存储字段,Compose 可以安全地进行跨模块 stability 推断——这是目前 data
class 做不到的。未来 Compose 甚至可以对 MFVC 参数进行属性级的变更追踪,只有当
user.name 或 user.nickname 实际变化时才触发重组,而不是整个 User 对象有任何变化都重组。
Named-only Parameters(仅命名参数 KEEP-0439)
引入 named 修饰符,强制调用者必须使用命名参数:
fun String.reformat(
named normalizeCase: Boolean,
named upperCaseFirstLetter: Boolean,
): String { /* body */
}
str.reformat(false, true) // 编译错误
str.reformat(normalizeCase = false, upperCaseFirstLetter = true) // OK
这对于有多个同类型参数(尤其是 Boolean)的函数非常有用,避免调用时搞混参数顺序。
lateinit val(KEEP-0455)
取代了早期的 KEEP-0452(Assign-Once Properties),填补了 lateinit var 和 val 之间的空白——允许延迟初始化,但只能赋值一次:
class MyActivity : AppCompatActivity() {
lateinit val view: ImageView // 只能赋值一次
override fun onCreate(savedInstanceState: Bundle?) {
view = findViewById(R.id.image) // 首次赋值 OK
// view = otherView // 再次赋值 → 编译错误或运行时异常
}
}
特性:线程安全的 backing field、支持 smart cast、支持 isInitialized 检查。根据调研,约 80% 的 lateinit var 使用场景实际上是
assign-once 语义。
设计讨论中,可能 2.6+
CoroutineContext as Context Parameter(KEEP-0443)
将 suspend 函数的隐式 CoroutineContext 与 context parameters 统一。目前 suspend 函数隐式携带 Continuation,其
context 属性本质上等价于 context parameter:
// 现在:通过 CoroutineContext 传递
suspend fun downDeepTheCallStack() {
println("Hello ${coroutineContext[User]?.name}!")
}
// 未来:通过 context parameter 传递(类型安全)
context(user: User)
fun downDeepTheCallStack() {
println("Hello ${user.name}!")
}
More Specific equals(KEEP-0456)
允许 equals 使用更具体的类型参数,而不是 Any?。编译器生成的 equals 也将携带受限类型,从而在使用点给出更好的诊断。这也是
MFVC 优化 == 比较的依赖项。
data class Point(val x: Int, val y: Int) {
// 编译器生成的 equals 将使用受限类型
operator fun equals(other: Point): Boolean = x == other.x && y == other.y
}
Point(1, 2) == "hello" // 编译时警告:Point 和 String 不可能相等
Typed Delegate Access(KEEP-0450)
允许在私有作用域内访问委托的类型化值,无需单独存储委托引用:
class C {
val dbConnection by lazy { connectToDb() }
fun close() {
// 直接访问 Lazy<DbConnection> 的 API,无需 reflection
if (::dbConnection.isInitialized()) {
dbConnection.close()
}
}
}
注:这可能统一 lateinit var 和委托属性,通过 assignOnce 委托实现 lateinit 语义。
Improve Compile-time Constants(KEEP-0444)
扩展 const val 支持的操作,统一各数值类型的行为:
// 目前不允许,未来可以:
const val secondsPerDay = 60u * 60u * 24u // unsigned 运算
const val receipt = """
1) apple
2) dough
""".trimIndent() // String stdlib 函数
引入 @CompileTimeCalculation 注解标记可在编译期执行的函数。
与其他语言的对比:Kotlin 的编译期求值目前远弱于 Zig 的 comptime 和 Rust 的 const fn。Zig 的 comptime
将编译期计算无缝集成到语言中,几乎任何函数都可以在编译期运行,甚至可以做泛型和代码生成;Rust 的 const fn 虽然有限制(只能调用其他
const fn),但已经支持相当复杂的编译期逻辑。
Kotlin 的 KEEP-0444 目前只是第一步——统一已有的 const val 行为、补上 unsigned
和部分 String 操作。未来文档中提到了 "Future Evolutions" 方向,@CompileTimeCalculation 可能让 Kotlin 逐步走向类似 Rust
const fn 的路径,但距离 Zig 那样的 comptime 级别还有很长的路。
Suspend Lambda Modifier(KEEP-0445)
补全 suspend lambda 和匿名函数的语法支持:
// 目前无法显式标记 lambda 为 suspend
val f = suspend { delay(100) } // 新语法
val g = suspendfun() { delay(100) } // 匿名 suspend 函数
解决 suspend/non-suspend 重载歧义问题。
Shared Internals(KEEP-0451)
引入 shared internal 可见性,允许模块间有限共享 internal 声明,解决 friend-module 需求。(类似于 C++ 的友元?)
部分重要特性状态总览
| 特性 | 状态 | 版本/KEEP | 预计时间 |
|---|---|---|---|
| Guard conditions | ✅ Stable | 2.2 | — |
| Non-local break/continue | ✅ Stable | 2.2 | — |
| Multi-dollar interpolation | ✅ Stable | 2.2 | — |
| Nested Type Aliases | ✅ Stable | 2.3 | — |
| Annotation use-site targets | ✅ Stable | 2.4 | — |
| Context Parameters | ✅ Stable | 2.4 | — |
| Context-sensitive Resolution | 🔬 Preview | 2.2+ | 可能 2.5 Stable |
| Explicit Backing Fields | 🔬 Experimental | 2.3 | 可能 2.5 Stable |
| Unused Return Value Checker | 🔬 Experimental | 2.3 | — |
| Version Overloading | 🔬 Experimental | 2.3 | 已可用 |
| Name-based Destructuring | 🔬 Experimental | 2.3.20 | — |
| Explicit Context Arguments | 🔬 Experimental | 2.4 | — |
| Collection Literals | 🔬 Experimental | 2.4, KEEP-0416 | — |
| Companion Blocks & Extensions | 🛠️ 实现中 | KEEP-0449/467 | 很可能 2.5 |
| Power-Assert Explanation | 🛠️ 原型 | KEEP-0458 | 2.4-Beta2 原型 |
| More Specific equals | 🛠️ 进行中 | KEEP-0456 | — |
| Shared Internals | 🛠️ 进行中 | KEEP-0451 | — |
| MFVC | 📐 Design | KEEP-0454 | 可能 2.5 Experimental |
| Rich Errors / Union Types | 📐 Design | KEEP-0441 | 可能 2.5~2.6 Preview |
| Named-only Parameters | 💬 讨论中 | KEEP-0439 | 可能 2.5~2.6 |
| lateinit val | 💬 讨论中 | KEEP-0455 | 可能 2.5~2.6 |
| Typed Delegate Access | 💬 讨论中 | KEEP-0450 | — |
| Compile-time Constants 改进 | 💬 讨论中 | KEEP-0444 | — |
| CoroutineContext as Context Param | 💬 讨论中 | KEEP-0443 | — |
| Suspend Lambda Modifier | 💬 讨论中 | KEEP-0445 | — |
| GADT Smart Casts | ❌ Declined | KEEP-0409 | — |
参考
部分参考已在文段中列出
- Kotlin 2.2.0: kotlinlang.org/docs/whatsn…
- Kotlin 2.3.0: kotlinlang.org/docs/whatsn…
- Kotlin 2.3.20: kotlinlang.org/docs/whatsn…
- Kotlin 2.4.0-Beta1: kotlinlang.org/docs/whatsn…
- Kotlin Roadmap (Feb 2026): kotlinlang.org/docs/roadma…
- KEEP Repository: github.com/Kotlin/KEEP
- Kotlin Language Features and Proposals: kotlinlang.org/docs/kotlin…