Kotlin 2.3.0 现已 发布!又有什么好东西?
大家吼哇,这次轮到 Kotlin 2.3.0 登场啦! 本次更新内容可以在 JetBrains 官方的 What's new in Kotlin 2.3.0 查阅, 我照例挑自己最感兴趣的改动聊聊。
一句话总结:Java 25 终于支持,特性体验逐渐舒适。实用功能层出不穷,小伙伴们赶快更新~
注意!这次依旧是「我个人 pick」的更新摘要,覆盖不了全部改动;对其他领域感兴趣、但是我没提到的伙伴可以继续深入官方文档喔。
文中示例如无特殊说明均来自或改写自官方日志。
语言特性
一如既往先看语言层面,首先映入眼帘的是对一部分实验特性的转正,然后是一批新晋实验特性,最后是对 Java 25 的支持。
一如既往的方阵阵营。
嵌套类型别名 & when 数据流穷举转正稳定
之前在 2.2.x 里加入的「嵌套 typealias 支持」(Support for nested type aliases)
和「基于数据流的 when 穷举检查」(Data-flow-based exhaustiveness checks for when expressions) 转正咯。
现在写多层 typealias 不会再有警告,
when 也会结合 smart cast 和 sealed 的上下文做更聪明的穷举判断了。
默认启用 suspend 解析 & 函数表达式里 return
注意:这个更新是在
2.3.0的某个 EAP 版本中描述的,但是在 2.3.0 正式版更新中没有描述,因此它可能被移除了。
Kotlin 2.3.0 默认启用了两项之前需要 -language-version 2.3 的特性:
- 传
lambda给既有suspend又有非suspend重载时,不再需要手动强转,直接写suspend { }就行。 - 函数表达式里允许
return,只需显式标注返回类型 。之前写fun foo() = return 42会报错,现在没事啦。
默认启用 body 中的 return 表达式特性
Kotlin 2.3.0 默认启用了之前 2.2.20 中更新的一个需要 -language-version 2.3 的特性:
在 body 表达式的局部使用 return。比如说:
fun getDisplayNameOrDefault(userId: String?): String = getDisplayName(userId ?: return "default")
未使用返回值检查器
新增了一个 -Xreturn-value-checker ,可以提示你「调用了有意义的返回值却没用」。
可以用来提前发现那种「写了一大串表达式结果却丢了」的 bug。
例如:
fun formatGreeting(name: String): String {
if (name.isBlank()) return "Hello, anonymous user!"
if (!name.contains(' ')) {
// 检查器会警告这个结果被忽略了
"Hello, " + name.replaceFirstChar(Char::titlecase) + "!"
}
val (first, last) = name.split(' ')
return "Hello, $first! Or should I call you Dr. $last?"
}
上面这段里,if 分支中构造了一段字符串却没有返回或赋值,检查器就会给出「结果被忽略」的警告。
默认情况下,这个检查器只对被标记了 @MustUseReturnValues 的作用域生效。
想要以 check 模式启用的话,可以在 build.gradle.kts 中这样写:
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xreturn-value-checker=check")
}
}
然后通过注解来声明「这里的返回值必须被使用」。可以标记整个文件:
// 标记整个文件:文件里的函数/类返回值若被忽略则会被检查器提示
@file:MustUseReturnValues
package my.project
fun someFunction(): String
也可以只标记某个类:
// 标记整个类:类中所有函数的返回值如果被忽略都会被检查器提示
@MustUseReturnValues
class Greeter {
fun greet(name: String): String = "Hello, $name"
}
fun someFunction(): Int = ...
如果你希望对整个项目的所有返回值都进行检查,可以开启 full 模式:
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xreturn-value-checker=full")
}
}
在这个模式下,相当于所有编译结果都隐式带上了 @MustUseReturnValues 标记。
有些函数的返回值被忽略是很正常的,比如 MutableList.add,这类就可以用 @IgnorableReturnValue 标记掉:
@IgnorableReturnValue
fun <T> MutableList<T>.addAndIgnoreResult(element: T): Boolean {
return add(element)
}
如果只是某一处调用想压制警告,又不想在函数签名上动刀,可以把结果赋值给下划线变量:
// 这是一个「不允许忽略返回值」的函数
fun computeValue(): Int = 42
fun main() {
// 这里会有警告:返回值被忽略
computeValue()
// 这里不会有警告:显式把返回值丢给一个特殊的 unnamed 变量
val _ = computeValue()
}
对于我这种偶尔写 DSL 忘记 return 的人来说,简直就是妥妥的保命符一张呀。