Releases

Kotlin 1.6.0 现已发布

Read this post in other languages:
English, Français, 한국어, Deutsch, Русский

Kotlin 1.6.0 现已正式发布,并带来了稳定版详尽 whens、Kover 和新版 Kotlin/Native 内存管理器。 1.5.30 版本中发布的其他语言和标准库功能也已达到稳定版。 感谢您与我们分享的反馈。 如果您还未尝试过这些新功能,现在正是时候!

在这篇博文中,您将会看到以下更新的概述:

  • 语言功能包含密封 when 语句、挂起函数与挂起转换、注解类的实例化、改进的常规类型推理和构建器类型推理。
  • Kotlin/JVM 包含优化的委托属性和可重复注解。
  • Kotlin/Native 包含新内存模型预览、Xcode 13 支持、Windows 目标交叉编译、LLVM 和链接器更新、性能更新以及统一编译器插件 ABI。
  • 为 Kotlin/JS 禁用下载 Node.js 和 Yarn 的选项。
  • Kover 公告。
  • 标准库包含针对标准输入的新函数、稳定版 typeOf()、稳定版 Duration API 以及其他稳定性得到提升的 stdlib 函数。

订阅我们的博客,不要错过任何 Kotlin 最新动态

如何升级

如果您使用的是 IntelliJ IDEA 或 Android Studio,您可以通过提供的选项在第一时间内自动更新至最新版本。

详细了解如何安装 Kotlin 1.6.0

Update to Kotlin 1.6.0

语言功能

我们基于您的反馈提升了 Kotlin 1.5.30 中功能的稳定性。

密封(详尽)when 语句

密封 when 是一项用户期待已久的功能,如果您的 when 语句不够详尽,Kotlin 编译器会发出警告。 这可以使您的代码更加安全,无需引入您自己的函数。

对于密封类、枚举和布尔类型,Kotlin 一直可以详尽地检查 when表达式。 这在使用这些代数数据类型进行领域建模时非常实用。 例如,对于建模为密封类层次结构的应用,您针对用户可能设有不同的联系偏好:

如果您编写的表达式是根据不同的联系偏好返回不同的结果,那么,在您忘记处理应用中的全部类型时,编译器将标记错误:

这对于代码编写和后续维护都很有帮助。 如果您以后添加不同类型的联系偏好,编译器将确保您不会忘记处理代码中的不同类型的联系偏好。

但是在 Kotlin 1.6 之前,以下使用 when语句的代码即便完全忘记处理通过即时通讯向用户发送通知,也能够成功编译。

此时仅仅会报告并不醒目的 IDE 检查,而编译器不会提供任何消息。 从 Kotlin 1.6 开始,会生成以下编译器警告:

Non-exhaustive 'when' statements on sealed class/interface will be prohibited in 1.7. Add an 'is InstantMessage' branch or 'else' branch instead.

在 Kotlin 1.7 中,警告将成为错误,以避免任何被意外遗漏的机会。 请参阅 KT-47709,了解有关变更及其影响的更详尽说明。 

将挂起函数作为父类型

Kotlin 1.6 已稳定支持将 suspend 函数类型实现为父接口。 这是 Kotlin 协同程序设计中缺失的部分之一。 在设计 Kotlin API 中需要自定义各种库函数的行为时,很自然会想到接受函数类型。 例如,kotlinx.coroutines API 的 Job 接口中具有类似于下例的成员函数:

您可以方便地将此函数与 lambda(例如 invokeOnCompletion doSomething() })搭配使用。 如果您有一个类要处理补全,则可以在类中直接实现函数类型 () -> Unit 来简化和优化代码,无需创建额外的 lambda:

自 Kotlin 1.6 开始,这种优化可以通过挂起函数实现。 如果您的 API 接受挂起函数类型,如下所示:

… 那么您将不再受限于只能将 lambda 和挂起函数引用传递至此代码。 您也可以在类中实现相应的挂起函数类型:

挂起转换

Kotlin 1.6 已稳定支持将常规函数转换为挂起函数类型。 您可以在以挂起函数为形参的方法中传递任何合适的常规函数类型的表达式。 编译器将自动执行转换。

这修正了 Kotlin 中常规函数和挂起函数之间微小但令人讨厌的交互不一致问题。 当您有一个接受挂起函数的高阶函数,例如在 Kotlin Flow 中调用 collect,但不通过 lambda 来调用,如下所示:

… 您会发现将 processItem 函数的引用传递至 collect 调用达到同样的效果会更加方便:

然后将处理函数的引用提取到变量中,便于自定义代码中的行为。 但是,这在 1.6 版本之前的 Kotlin 中无效。 这是因为有一个作为挂起类型的形参传递的常规函数:

在 Kotlin 1.6 中,上面的代码可以顺利编译和工作。

改进了递归泛型类型的类型推理

从 1.6.0 版本开始,如果默认情况下为递归泛型,则 Kotlin 编译器可以仅根据对应类型形参的上限来推断类型实参。 这使得创建泛型递归的各种模式成为可能,这些泛型通常用于 Java 的建造者模式 API。

构建器推理的改进

Kotlin 1.5.30 引入了 -Xunrestricted-builder-inference 编译器选项,让构建器调用的类型信息可以在构建器 lambda 中获取。 也就是说,它引入了调用返回尚未推理类型的实例的能力,例如 buildList() lambda 中的 get()

从 1.6.0 版本开始,无需指定 -Xunrestricted-builder-inference 进行以前禁止的调用。 现在,您还可以使用 -Xenable-builder-inference 编译器选项编写自己的泛型构建器,而不需要应用 @BuilderInference 注解,且如果常规类型推理无法解析类型信息,您还可以自动启用构建器推理。

长期支持以前的 API 版本

从 Kotlin 1.6.0 开始,您现在可以使用三个以前的 API 版本进行开发,而非两个(外加当前稳定版本)。 目前,可用的 API 版本包括 1.3、1.4、1.5 和 1.6。

Kotlin/JVM

具有运行时保留的可重复注解。Kotlin 与 Java 8 一样具有可重复注解。 在 Kotlin 1.6 中,该功能与 Java 兼容,@kotlin.annotation.Repeatable 现在接受任何保留并让注解在 Kotlin 和 Java 中都可重复。 Kotlin 端现在也支持 Java 可重复注解。

Kotlin/Native

现在,您可以尝试新 Kotlin/Native 内存管理器的实验版。 此功能致力于在多平台项目中提供一致的开发者体验。 新的内存管理器解除了对线程间对象共享的现有限制,并提供完全无泄漏的并发编程基元,这些基元是安全的,不需要开发者进行任何特殊管理或注解。

您可以随意更新 Xcode 并继续处理 Kotlin 项目,因为 Kotlin/Native 现已支持 Xcode 13

在任何主机上编译 Windows 目标。现在,您可以在任何支持 Kotlin/Native 的主机上编译 Windows 目标 mingwX64 和 mingwX86

我们重做了 Kotlin/Native 在后台使用的 LLVM 依赖项。 这将 LLVM 版本更新到了 11.1.0、缩减了依赖项大小,并带来了一些额外好处。

JVM 和 JS IR 后端的统一编译器插件 ABI。 现在,Kotlin Multiplatform Gradle 插件能够将可嵌入编译器 jar(原用于 JVM 和 JS IR 后端)用于 Kotlin/Native。 您现在可以为 Native 和其他受支持平台使用相同的编译器插件工件。

Kotlin/JS

如果是在没有互联网连接的服务器上进行构建,您可以为 Kotlin/JS 项目禁用下载 Node.js 和 Yarn,并使用主机上已安装的实例。

Kover

从第一个版本开始,精准衡量代码覆盖率始终是一项不小的挑战。 JaCoCo 等出色工具虽然支持 Kotlin 代码,但并未与我们的 Gradle 工具链和多平台项目完全集成。 在此 Kotlin 版本中,我们已着手修正此问题。 新的 Gradle 插件 Kover 可以对使用 Kotlin/JVM 编译器构建的 Kotlin 代码衡量代码覆盖率。 当前它仍处于早期开发阶段并且为实验性,我们非常期待您在 GitHub 中提供反馈。

观看 Kover 视频了解更多详情

标准库

Kotlin 1.6.0 通过在 readLine() 之后去除 !!稳定 typeOf() 和提供稳定版 Duration API 完成了三个 stdlib 路线图条目。 它还将以下 stdlib 函数提升到了稳定版

  • 集合构建器
  • 整数的位旋转运算
  • 用于将字符串拆分为序列的正则表达式函数

我们还添加了以中缀表示法调用 compareTo 的功能,并在 JVM 和 JS 上推动以 replace() 函数提供一致的体验。

标准输入的新函数

在 Kotlin 1.6.0 中,从标准输入读取一行后不再需要使用非 null 断言运算符 !!,这将改善新手体验并简化 Kotlin 教学。我们为从控制台读取提供了新函数,流程如下:

  • readln() 在到达 EOF 时抛出异常。 使用此函数替换以 !! 运算符检查 readLine() 的结果是否为 null
  • 新的 readlnOrNull() 是返回 null 的替代方案。 其行为与先前的 readLine() 相同,但具有代表性更强的名称。

这些函数现在可用于 JVM 和 Native。 这些函数的命名惯例现在与对应的 println() 一致,这对新手尤其重要。

稳定版 Duration API

基于反馈,我们已经稳定了 Duration API 并关闭了相应的路线图条目

除了更易读的 Duration.toString() 输出以及用于从 String 解析 Duration 的新函数(可在 1.5.30 中预览)之外,Duration API 还具有以下变更:

  • toComponents 函数的 days 组件现在具有 Long 类型而不是 Int ,避免截断值。
  • DurationUnit 枚举现在不是类型别名。 没有将它用作 JVM 上 java.util.concurrent.TimeUnit 的类型别名的情况。
  • 为回应社区反馈,我们将恢复 Int.seconds 等扩展属性。 为限制其适用性,它们仅在 Duration 类的 Companion 中可用。

稳定版 typeOf()

Kotlin 1.6.0 带来了稳定版typeOf() 并关闭了相应的路线图条目。 自 1.3.40 起,typeOf() 作为实验性 API 在 JVM 平台上推出,现已可用于所有 Kotlin 平台,您可以获得编译器可推断的任何 Kotlin 类型的 KType 表示。

稳定版集合构建器

Kotlin 1.6.0 已将 buildMap()buildList() 和 buildSet() 集合构建器函数提升到稳定版。 构建器返回的集合现在可以在只读状态下序列化。

稳定版整数位旋转运算

在 Kotlin 1.6.0 中,将数字二进制表示向左或向右旋转指定位数的 rotateLeft() 和 rotateRight() 函数已经稳定

用于将字符串拆分为序列的稳定版正则表达式函数

Kotlin 1.6.0 还稳定了用于将字符串拆分为序列的正则表达式函数 splitToSequence()

中缀表示法的 compareTo

我们添加了以中缀表示法调用 Comparable.compareTo 函数来比较两个对象的顺序的功能: 

JVM 和 JS 上的一致 replace() 和 replaceFirst()

在 Kotlin 1.6.0 之前,当替换字符串包含组引用时,replace() 和 replaceFirst() 正则表达式函数在 JVM 和 JS 上具有不同的行为。 Kotlin/JS 上的行为现在将与 JVM 上的行为一致。

​​兼容性

与所有功能版本一样,先前宣布的变更的部分弃用周期将在 Kotlin 1.6.0 中结束。 所有情况均已经过语言委员会的仔细审查,并在 Kotlin 1.6 兼容性指南中列出。 您也可以在 YouTrack 上了解这些变更。

如何安装 Kotlin 1.6.0

如果您使用的是 IntelliJ IDEA 或 Android Studio,您的 IDE 会自动建议将 Kotlin 更新到 1.6.0。 或者,您也可以按照这些说明手动更新。您仍然可以下载这些 IDE 的最新版本以获取对 Kotlin 的全面支持:

  • IntelliJ IDEA – 用于为不同平台开发 Kotlin 应用程序。
  • Android Studio – 用于开发 Android 和跨平台移动应用程序。

确保您已将 kotlinx 库更新到兼容版本,并在现有项目的构建脚本中指定 Kotlin 1.6.0。如果需要命令行编译器,可从 Github 版本页面下载。

如果遇到任何问题:

及时了解 Kotlin 最新功能! 填写本文右侧的表单,订阅接收 Kotlin 的最新动态。

其他文章和视频

YouTrack 上的最佳问题报告者

Ryan Nett(48 个问题),Zac Sweers(22 个问题),Tianyu Geng(18 个问题),zhelenskiy(18 个问题),Thodoris Sotiropoulos(15 个问题),AndroidDeveloperLB(14 个问题),Morgan, Bartholomew(14 个问题),Mikhail Naftal(14 个问题),Louis CAD(12 个问题),Philip Wedemann(12 个问题),Victor Turansky(11 个问题),Igor Wojda(11 个问题),Martin Bonnin(11 个问题),Iaroslav Postovalov(11 个问题),Cedric(10 个问题),(9 个问题),Ben Woodworth(8 个问题),Tianyi Guan(8 个问题),Chris Povirk(8 个问题),Alon Albert(8 个问题)。

外部贡献者

我们要感谢此版本所含拉取请求的所有贡献者:PyosTianyu GengJinseong JeonSteven SchäferMark PunzalanHung NguyenMads AgerTing-Yuan HuangMatthew GharrityIvan GavrilovicXin Wangov7aJiaxiang ChenYigit BoyarBingranbracadabraSteffi StumposAndrey Kuleshov

本文博文原作者:

Sue

Alina Grebenkina

特别感谢由来自 Kotlin 社区的 黄智聪 (pye52) 参与贡献本文翻译。

Discover more