Kotlin 2.2~2.4 更新速览与 2.5+ 展望

3 阅读7分钟

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 ParametersContext-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,现在可以直接使用 breakcontinue

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(上下文参数)

github.com/Kotlin/KEEP…

这是一个重大新特性,用于替代之前实验性的 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(上下文敏感解析)

github.com/Kotlin/KEEP… youtrack.jetbrains.com/issue/KT-16…

在过去,即使编译器可以推断出类型,我们仍然必须写全名。现在,在能推断出类型的位置,可以省略限定名:

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 FieldsUnused 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(未使用返回值检查器)

github.com/Kotlin/KEEP…

新的编译器检查器,可以在返回值被忽略时发出警告。通过 @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)

github.com/Kotlin/KEEP…

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(基于名称的解构)

github.com/Kotlin/KEEP…

这是一个重新设计解构声明的重大提案。过去的解构基于位置(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(显式上下文参数)

github.com/Kotlin/KEEP…

为了解决 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)

github.com/Kotlin/KEEP…

进度分析:提案文本完整,有工作原型分支,性能基准测试已完成。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 objectoperator 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)

github.com/Kotlin/KEEP…

该提案是早期 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)

github.com/Kotlin/KEEP… github.com/Kotlin/KEEP…

这可能是 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 Eitherkotlin.Result 或自定义 Result 类型的项目,Rich Errors 将提供更轻量、无包装的原生替代方案。

Better Immutability / Value Classes 2.0(KEEP-0453/0454)

github.com/Kotlin/KEEP… github.com/Kotlin/KEEP…

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.nameuser.nickname 实际变化时才触发重组,而不是整个 User 对象有任何变化都重组。

Named-only Parameters(仅命名参数 KEEP-0439)

github.com/Kotlin/KEEP… youtrack.jetbrains.com/issue/KT-14…

引入 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)

github.com/Kotlin/KEEP…

取代了早期的 KEEP-0452(Assign-Once Properties),填补了 lateinit varval 之间的空白——允许延迟初始化,但只能赋值一次:

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)

github.com/Kotlin/KEEP…

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)

github.com/Kotlin/KEEP…

允许 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)

github.com/Kotlin/KEEP…

允许在私有作用域内访问委托的类型化值,无需单独存储委托引用:

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)

github.com/Kotlin/KEEP…

扩展 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)

github.com/Kotlin/KEEP…

补全 suspend lambda 和匿名函数的语法支持:

// 目前无法显式标记 lambda 为 suspend
val f = suspend { delay(100) }              // 新语法
val g = suspendfun() { delay(100) }        // 匿名 suspend 函数

解决 suspend/non-suspend 重载歧义问题。

Shared Internals(KEEP-0451)

github.com/Kotlin/KEEP…

引入 shared internal 可见性,允许模块间有限共享 internal 声明,解决 friend-module 需求。(类似于 C++ 的友元?)

部分重要特性状态总览

特性状态版本/KEEP预计时间
Guard conditions✅ Stable2.2
Non-local break/continue✅ Stable2.2
Multi-dollar interpolation✅ Stable2.2
Nested Type Aliases✅ Stable2.3
Annotation use-site targets✅ Stable2.4
Context Parameters✅ Stable2.4
Context-sensitive Resolution🔬 Preview2.2+可能 2.5 Stable
Explicit Backing Fields🔬 Experimental2.3可能 2.5 Stable
Unused Return Value Checker🔬 Experimental2.3
Version Overloading🔬 Experimental2.3已可用
Name-based Destructuring🔬 Experimental2.3.20
Explicit Context Arguments🔬 Experimental2.4
Collection Literals🔬 Experimental2.4, KEEP-0416
Companion Blocks & Extensions🛠️ 实现中KEEP-0449/467很可能 2.5
Power-Assert Explanation🛠️ 原型KEEP-04582.4-Beta2 原型
More Specific equals🛠️ 进行中KEEP-0456
Shared Internals🛠️ 进行中KEEP-0451
MFVC📐 DesignKEEP-0454可能 2.5 Experimental
Rich Errors / Union Types📐 DesignKEEP-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❌ DeclinedKEEP-0409

参考

部分参考已在文段中列出

其他