
Kotlin 1.7.0 的首个预览版现已发布,以下是 Kotlin 1.7.0-Beta 的一些亮点:
构建器推断变更。
min() 和 max() 集合函数回归。
绝对不可空类型得到稳定。
新版 Kotlin/Native 内存管理器更新。

从 1.7.0 开始,我们更新了我们的发布节奏术语:将“Milestone”(里程碑)更改为“Beta”(测试版)。 这一决定背后有几个原因:
我们希望 Kotlin 构建术语更加符合软件发布周期的标准术语。 更准确地说,“Beta”意味着我们向该特定版本中添加新功能的工作已经完成,并且正在致力于稳定工作。 不过,我们也会实现最终变更,包括基于用户反馈的变更。
前段时间,M-release 编译器一直在生成“预发布”代码,这使得这些版本更难测试。 现在完全不一样了。 我们希望避免任何混淆,并强调试用 Kotlin Beta 版本的过程将十分简单,并且 Kotlin 团队非常鼓励大家试用这一版本。
最后但同样重要的一点是,“Beta”一词本身就有呼吁社区提供反馈的意味。 借此术语,我们想让您知道我们希望您能与我们分享反馈。
构建器推断变更
构建器推断是一种特殊的类型推断,在调用泛型构建器函数时很有帮助。 它可以帮助编译器推断调用的类型实参,方法是使用其 lambda 实参中其他调用的相关类型信息。
Kotlin 1.7.0-Beta 中包含了针对构建器推断的更多变更。 这些变更使我们的构建器推断趋于稳定,我们在路线图中的任务之一也趋于完成。
在此版本中,如果常规类型推断无法获得有关类型的足够信息,则无需指定 -Xenable-builder-inference
编译器选项(我们在 1.6.0 版本中引入),即可自动激活构建器推断。
这意味着现在您无需应用任何额外的注解或选项,即可编写自己的使用构建器类型推断的构建器。 了解如何编写自定义通用构建器:https://kotlinlang.org/docs/using-builders-with-builder-inference.html
min() 和 max() 集合函数回归
在 Kotlin 1.4 中,我们将min()
和max()
集合函数重命名为minOrNull()
和maxOrNull()
。 这些新的名称能够更好地反映它们的行为 —— 如果接收器集合为空,则返回null
。 它还有助于使函数的行为与整个 Kotlin Collections API 中使用的命名惯例保持一致。
minBy()
、maxBy()
、minWith()
和maxWith()
同样如此,在 Kotlin 1.4 中均具有自己的*OrNull()
同义词。 受此变更影响的旧函数已逐渐弃用。
Kotlin 1.7.0-Beta 重新引入了原始的函数名称,但加入了不可空返回类型。 现在,更新后的min()
、max()
、minBy()
、maxBy()
、minWith()
和maxWith()
会严格返回集合元素或抛出异常。
fun main() {
val numbers = listOf<Int>()
println(numbers.maxOrNull()) // "null"
println(numbers.max()) // "Exception in… Collection is empty."
}
请参见此 YouTrack 问题以了解详情:https://youtrack.jetbrains.com/issue/KT-38854
绝对不可空类型得到稳定
Kotlin 1.7.0 将具有稳定的绝对不可空类型,这些类型是在 Kotlin 1.6.20 中引入的。
添加这些类型的目的是在扩展泛型 Java 类和接口时提供更好的互操作性。
自 Kotlin 1.6.20 起,您已经能够使用新语法T & Any
在使用站点上将泛型类型形参标记为绝对不可空。 该语法形式来自相交类型表示法,现在被限制为一个类型形参,&
左侧为可空上限,右侧为不可空Any
:
fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y
fun main() {
elvisLike<String>("", "").length // OK
elvisLike<String>("", null).length // Error: 'null' cannot be a value of a non-null type
elvisLike<String?>(null, "").length // OK
elvisLike<String?>(null, null).length // Error: 'null' cannot be a value of a non-null type
}
在此测试版中,将默认启用绝对不可空类型。 无需其他步骤。
在 KEEP 中详细了解绝对不可空类型:https://github.com/Kotlin/KEEP/blob/c72601cf35c1e95a541bb4b230edb474a6d1d1a8/proposals/definitely-non-nullable-types.md
正则表达式特定位置匹配
在 1.5.30 中引入的Regex.matchAt()
和Regex.matchesAt()
函数现已达到稳定版本。 它们提供了一种方式来检查正则表达式在String
或CharSequence
中的特定位置是否具有精确匹配。
-
matchesAt()
可以检查匹配并返回布尔结果:
fun main(){
val releaseText = "Kotlin 1.7.0 is on its way!"
// regular expression: one digit, dot, one digit, dot, one or more digits
val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
println(versionRegex.matchesAt(releaseText, 0)) // "false"
println(versionRegex.matchesAt(releaseText, 7)) // "true"
}
-
matchAt()
会在找到匹配的情况下返回匹配,在未找到匹配的情况下返回null
:
fun main(){
val releaseText = "Kotlin 1.7.0 is on its way!"
val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
println(versionRegex.matchAt(releaseText, 0)) // "null"
println(versionRegex.matchAt(releaseText, 7)?.value) // "1.7.0"
}
我们将非常感谢您在此 YouTrack 问题中提供反馈:https://youtrack.jetbrains.com/issue/KT-34021
新版 Kotlin/Native 内存管理器
我们将继续收集反馈,并改进新版 Kotlin/Native 内存管理器。 目前,您可以在项目中试用 Alpha 版本。Kotlin 1.7.0-Beta 带来了更多性能改进,这些改进将提升开发者体验。
新版内存管理器消除了 JVM 与 Native 平台之间的差异。 它在多平台项目中提供了一致的开发者体验。 例如,您可以更加轻松地开发同时适用于 Android 和 iOS 平台的新款跨平台移动应用程序。
新版 Kotlin/Native 内存管理器解除了线程间对象共享的限制。 它还提供了安全且无需任何特殊管理或注解的无泄漏并发编程语言基元。新版内存管理器将成为未来版本中的默认管理器,因此我们鼓励您立即试用。
详细了解新版内存管理器并探索演示项目:https://blog.jetbrains.com/kotlin/2021/08/try-the-new-kotlin-native-memory-manager-development-preview/
或直接跳转到迁移说明以亲自试用:https://github.com/JetBrains/kotlin/blob/master/kotlin-native/NEW_MM.md
在您的项目中试用新版内存管理器以了解其运作方式,并在我们的问题跟踪器 YouTrack 中分享您的反馈:https://youtrack.jetbrains.com/issue/KT-48525
JS 和 Native 中的命名捕获组支持
从 Kotlin 1.7.0-Beta 起,不仅在 JVM(1.8 及更高版本)上支持,在 JS 和 Native 上也将支持命名捕获组。
要为捕获组命名,请在正则表达式中使用(?<name>group)
语法。 要获取组匹配的文本,请调用新引入的MatchGroupCollection.get()
函数并传递组名。
按名称检索匹配的组值
请思考这个匹配城市坐标的示例。 要获取正则表达式匹配的组的集合,请使用groups
。 比较使用value
按组的编号(索引)和按组的名称来检索组的内容:
fun main() {
val regex = "\\b(?<city>[A-Za-z\\s]+),\\s(?<state>[A-Z]{2}):\\s(?<areaCode>[0-9]{3})\\b".toRegex()
val input = "Coordinates: Austin, TX: 123"
val match = regex.find(input)!!
println(match.groups["city"]?.value) // "Austin" — by name
println(match.groups[2]?.value) // "TX" — by number
}
命名向后引用
现在,您在向后引用组时还可以使用组名。 向后引用会匹配捕获组先前匹配的相同文本。 为此,请在正则表达式中使用\k<name>
语法:
fun backRef() {
val regex = "(?<title>\\w+), yes \\k<title>".toRegex()
val match = regex.find("Do you copy? Sir, yes Sir!")!!
println(match.value) // "Sir, yes Sir"
println(match.groups["title"]?.value) // "Sir"
}
替换表达式中的命名组
最后,命名组引用可以与替换表达式一起使用。 请思考用于将输入中出现的所有正则表达式替换为替换表达式的replace()
函数,以及仅交换第一个匹配项的replaceFirst()
函数。
替换字符串中出现的各个${name}
会被替换为与具有指定名称的捕获组对应的子序列。 比较按名称和按索引替换组引用:
fun dateReplace() {
val dateRegex = Regex("(?<dd>\\d{2})-(?<mm>\\d{2})-(?<yyyy>\\d{4})")
val input = "Date of birth: 27-04-2022"
println(dateRegex.replace(input, "\${yyyy}-\${mm}-\${dd}")) // "Date of birth: 2022-04-27" — by name
println(dateRegex.replace(input, "\$3-\$2-\$1")) // "Date of birth: 2022-04-27" — by number
}
试用新功能并提供反馈
您可以在 1.7.0 预览版 Kotlin 1.7.0-Beta 中使用这些新功能。 您可以轻松地将它安装在 IntelliJ IDEA 或 Android Studio IDE 中。
由于 Android Studio 插件重命名(测试版),支持在 1.6.20 及后续版本中安装插件。
请通过以下任一方式安装 Kotlin 1.7.0-Beta:
如果您使用抢先体验预览更新通道,IDE 将在 1.7.0-Beta 可用时立即建议自动更新至该版本。
如果您使用稳定版更新通道,则可以随时在您的 IDE 中选择 Tools | Kotlin | Configure Kotlin Plugin Updates(工具 | Kotlin | 配置 Kotlin 插件更新)以切换至抢先体验预览通道。 然后,您将能够安装最新的预览版。
请参阅说明以了解详情:https://kotlinlang.org/docs/install-eap-plugin.html
完成 1.7.0-Beta 安装后,不要忘记在您的构建脚本中将 Kotlin 版本更改为 1.7.0-Beta:
请参阅:https://kotlinlang.org/docs/configure-build-for-eap.html
如果您遇到任何问题:
向我们的问题跟踪器 YouTrack 报告问题。
https://kotl.in/issue
在 Kotlin Slack 中的 #eap 频道 中获取帮助。
https://app.slack.com/client/T09229ZC6/C0KLZSCHF
(需提前申请以加入群组:https://surveys.jetbrains.com/s3/kotlin-slack-sign-up)
回滚到最新的稳定版本。参阅:
https://kotlinlang.org/docs/install-eap-plugin.html
本博文英文原作者:Danil Pavlov

⏬ 戳「阅读原文」了解更多
本文分享自微信公众号 - JetBrains(JetBrainsChina)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。