Kotlin 1.3.70正式发布

今天我们很高兴地向你介绍目前Kotlin最新的版本1.3.70。

kotlin_1370

该增量版本不会有新的功能。这是因为我们在尽力去改善现有功能,解决问题,和添加可供尝试的实验性功能。下面介绍Kotlin 1.3.70的重点:

  • 在Kotlin标准库集合中的新函数和类。
  • 针对IntelliJ Kotlin插件的各种改进::改进了* .gradle.kts的支持,测试,调试,补全等。
  • 现在Kotlin/JVM编译器会对Java 8以及更高版本的字节码生成类型注解。
  • Bundle优化,npm依赖项声明以及期待已久的新Kotlin/JS文档。
  • 编译和调试速度更快的Kotlin/Native
  • 改进了IDE和命令行工具中对脚本的支持。

你可以在更新日志查看完整的变动列表。一如既往,我们非常感谢其他贡献者

更多的细节请听我娓娓道来。

标准库的变化

请注意,所有新函数都以实验状态添加到了标准库中。

基础库中StringBuilder的扩展

虽然StringBuilder已包含在标准库common的kotlin.text包。但却缺失了许多重要属性,也仅能在JVM上使用。而现在,JVMStringBuilder的所有功能都已添加到了平台相关的通用Expect类。这意味着你可以从通用代码中使用StringBuilder所有属性。

Working with KClass

现在JVM上KClass的部分基础属性不再需要依赖kotlin-reflect了:

在之前,你需要在运行时提供Kotlin reflection实现以使其工作。而现在,你可以不需要任何依赖就能使用这些简单属性。

重命名实验注解(@Experimental和@UseExperimental)

如你所知,Kotlin内置能使用实验特性的机制。包括标准库中的注解,它们本身就是实验性的或使用其他实验性声明标记的。在以前的版本,这些注解是@UseExperimental@Experimental

我们决定扩大此机制的范围,因为使用实验性的API还需要同意其他的要求。例如,API可以是内部的,也可以有一些限制。我们对注解的重命名正是反映这一点:名称@OptIn@RequiresOptIn分别代替了@UseExperimental@Experimental。编译器参数-Xuse-experimental已重命名为-Xopt-in。至于-Xexperimental,它的使用频率低且会增加复杂性,因此我们将它删除了。虽然 1.3.70仍支持旧的声明@Experimental@UseExperimental,但在1.4中它们将被删除。

重命名实验性的时间测量API

我们也重命名了持续时间和时间测量APIClockClockMark已重命名为TimeSourceTimeMark。而以前的名称现在作为不推荐使用的类型别名保留了下来。

双端队列实现:ArrayDeque

我们很高兴地将双端队列的实现kotlin.collections.ArrayDeque类添加到了Kotlin标准库中!这是社区一直梦寐以求的。即便可以使用Java标准库中的java.util.ArrayDeque类,但对于Kotlin/JS,Kotlin/Native以及通用代码,都没有合适的实现。现在,尽管还处于实验状态,也至少是可用的实现了。

双端队列允许你以均摊时间向队列的开头和结尾添加/删除元素:

当你的代码中需要队列或堆栈时,默认情况下可以使用双端队列。

Kotlin.collections.ArrayDeque底层实现是一个可变长的数组:它将内容存储在循环缓冲区——一个数组,并仅在数组存满时才调整其大小。

从概念上讲,ArrayDeque的实现与java.util.ArrayDeque的实现非常相似。但请注意,这实际上是不同的实现,且当你在Kotlin/JVM上使用这个类时,将使用新的实现。这与其他集合的工作方式不同:创建ArrayList并在JVM进行编译时,其背后会使用java.util.ArrayList类。与Java的ArrayDeque仅实现Collection接口不一样的是,Kotlin的ArrayDeque实现了MutableList。这意味着你可以通过索引访问所有元素,而这是Java的ArrayDeque无法实现的。

我们现在以实验状态发布ArrayDeque类,并期待你的反馈!

集合Builder

另一个重要的新功能是集合的builder函数:buildListbuildSetbuildMap。你可以使用这样的builder函数在创建阶段方便地操作可变集合,并最终得到一个只读的集合:

这些builder函数的实现与buildString类似。 buildList允许传入带有接收者的lambda作为参数。 Lambda中的隐式“ this”接收器的类型为MutableList,而buildList返回一个只读的List作为结果。

在操作较为复杂(例如需要条件,修改多个初始集合或合并结果等)时,使用builder函数通常更具可读性和更有效(原文为more effective in terms of performance)。请注意,这些功能目前还处于实验状态。

reduceOrNull()和randomOrNull()

你知道Kotlin中的约定:通常会有这样一对函数,其中第一个函数在无法执行操作时引发异常,第二个函数返回null,例如string.toInt()string.toIntOrNull()。现在,我们按照相同的约定添加了新的randomOrNull()reduceOrNull()函数:

如果你使用random()reduce(),当集合为空时会抛出一个异常。

scan()函数

我们添加了一组用于处理列表和序列的新函数。它们代表“扫描”的概念;类似的功能已经存在于各类型的语言当中。

scan()fold()密切相关。 scan()fold()都将给定的二进制运算应用于值序列,但是不同之处在于scan()返回包含中间结果的序列,而fold()仅返回最终的结果。

scan也像fold一样也需要初始值进行累加:

img

如果结果类型与元素类型相同,并且可以将第一个元素用作初始值,则可以使用reduce()scanReduce()函数:

img

请注意,在序列上使用scan()scanReduce()时,将返回一个结果序列,这些序列本质上是惰性的。这意味着只有你从结果序列中查询数据,特别是调用终止操作(返回另一个序列以外的其他值),例如toList()max()时,扫描过程才会开始。在列表上使用scan()scanReduce()时,将会返回一个列表作为结果。

阅读KEEP以了解更多细节。

IntelliJ IDEA的支持

该版本包括IntelliJ IDEA中对Kotlin支持的一些改进。让我们来看看最值得关注的地方。

对*.gradle.kts的支持

在1.3.70中,我们致力于改进IntelliJ IDEA对Gradle Kotlin DSL脚本(* .gradle.kts文件)的支持。最新版本的Kotlin插件在语法高亮,代码补全,代码搜索以及其他使用Kotlin构建脚本的方面,性能表现非常优秀。博文对这项改进有更进一步的讨论。 要享受到所有变化和改进,请确保使用IntelliJ IDEA 2019.2或更高的版本,同时使用Gradle 6.0或更高的版本。

代码补全

在1.3.70中,我们对IntelliJ IDEA中的Kotlin代码补全进行了显着的改进。现在,补全建议包含对象中声明的函数,扩展函数,以及object层级重写的函数,甚至是嵌套对象中声明的函数。

object-extension-completion

我们还改进了针对补全列表排序的机器学习模型,现在,最相关的选项将会显示在顶部。

新的配色方案

为了使你可以根据自己的喜好更改编辑器中Kotlin代码的外观,我们添加了新的可自定义的配色方案。特别现在你可以为suspend函数调用和属性声明设置自己的配色方案了。

suspend-color-scheme

调试的改进

在之前的版本中,Kotlin/Native调试器曾经有一个单独的断点类型,这使部分用户难以选择,例如“我应该在这里使用哪种断点类型?”。而现在只有一个断点类型Kotlin Line Breakpoint,用于JVM和Native。

Kotlin/JS和Kotlin/Native测试

与Kotlin/JVM测试一样,现在可以在IntelliJ IDEA中直接显示Kotlin/JS和Kotlin/Native的测试结果。另外,我们已经修复了Kotlin/JS的测试过滤功能,因此你可以运行单独的测试,并且最后还可以通过点击Play按钮直接启动面向iOS模拟器的Kotlin/Native测试。

img

此外,在IntelliJ IDEA Ultimate中,你可以通过单击测试声明附近的图标来启动Kotlin/JS调试。

img

另外,你可以通过在Gradle工具窗口中手动选择nodeRunnodeTestbrowserTest任务来开始调试。对于browserRun,可以在开发服务器启动后通过Attach to Node.js/Chrome 运行配置来连接到调试器。

其他应该关心的提醒

IntelliJ IDEA中对Kotlin支持还进行了其他改进。这里有部分值得一提的:

  • 改进了文件分析和复制粘贴操作的性能。
  • 新的对无意义的一元运算符的检查。它们可能会在将长表达式拆分成多行时出现:
  • 大量格式化方面的改进,包括链式调用,换行符,空格和注解的格式化。

Kotlin/JVM

Kotlin现在可以在JVM字节码(版本1.8以上)中生成类型注解,以便它们在运行时可用。社区对该特性的要求已经有一段时间了,因为它让使用某些现有Java库更加容易,并且为那些编写新库的人提供了更多功能。

在以下示例中,String类型所标记的@Foo注解将输出到字节码中,其提供给库代码去使用:

要在字节码中输出类型注解,请按照下列步骤操作:

  • 确保声明的注解有合适的对象范围(Java的ElementType.TYPE_USE或Kotlin的AnnotationTarget.TYPE)和可见性(AnnotationRetention.RUNTIME)。
  • 使用此注解(以上示例中的Class A)将注解类声明和代码编译版本为1.8以上的JVM字节码。你可以通过设置-jvm-target=1.8编译器配置来实现。
  • 使用带有-Xemit-jvm-type-annotations编译器配置的注解来编译代码。

请注意,由于标准库的类型注解是使用目标版本1.6进本编译的,因此暂时不会输出到字节码中。

到目前为止,仅支持基本的使用场景:

  • 方法参数,方法返回类型和属性类型的类型注解;
  • 类型参数的不变投影,例如Smth<@Ann Foo>Array<@Ann Foo>

未来,我们计划支持为协变和逆变类型投影,以及内部类型的注解(例如Smth<@Ann Outer.Inner>)生成类型注解。我们认为,当前已支持的场景,应该已涵盖了大多数实际使用情况,但是如果你需要更复杂场景的类型注解,请告诉我们。

Kotlin/JS

在Kotlin 1.3.70,JavaScript目标平台在bundle的大小方面进行了一些重大的优化,并在处理依赖,资源和测试的方式上增加了一些提升体验的改动。我们也很高兴地宣布针对该目标平台的文档进行了全面的修订。

Bundle优化

从Kotlin 1.3.70开始,现在可以通过org.jetbrains.kotlin.js Gradle插件轻松获得DCE(消除无效代码),而无需手动去添加。它会接收一组新任务,可用于控制JS项目的优化和执行。

在开发过程中,使用browserDevelopmentRun会以不执行优化的方式启动应用程序及捆绑的开发服务器。使用browserDevelopmentWebpack可以在build/distributions文件夹中生成应用程序的非优化bundle包。如果选择不运行任何优化,则构建时间将更快,但是编译后的程序文件体积会更大。

而在生产环境,请使用browserProductionRun对应用程序的进行优化,并使用browserProductionWebpack生成适合在生产环境中部署的bundle。生产版本的编译时间要更长一点,但对比开发版本会有显著的优化:

项目开发版本 (GZIP)生产版本 (GZIP)
“Hello, World”963 KiB14 KiB
Kotlin/React Example (“CodeQuiz”)4.1 MiB345 KiB

尽管之前的Gradle任务browserRu(现在是browserDevelopmentRun的别名)和browserWebpack(现在是browserProductionWebpack的别名)仍然可用,但是你应该在构建脚本中使用它们的新”身份”来代替。

这些Gradle任务可运行于使用了多平台kotlin.jsGradle插件的项目。对于kotlin.js,你还可以使用短的任务别名去运行browserDevelopmentRun和针对browserProductionWebpack进行构建

如果你想了解Kotlin/JS中消除无效代码,和如何以细粒度方式进行配置的更多信息,请查阅文档

资源自动复制

现在,在分发文件夹(如browserProductionWebpack)中创建bundle的构建任务,现在也会从resources文件夹中复制所有资源,因此不再需要手动去复制图片,样式表等等来获取可部署的组件。

对npm依赖声明的平滑支持

使用Kotlin/JS Gradle插件时,现在可以在顶级依赖块中声明npm依赖,而不必手动添加主要源集。这意味着以下代码段现在是合法的:

对Gradle测试的实验性调试

现在对面向浏览器的Kotlin/JS测试,可以直接在IntelliJ IDEA中进行调试了。要调试失败(原文为failing)的测试,请在IDE中设置一个断点,然后以调试模式启动Gradle任务check,或通过gutter图标来对整组测试进行调试。 Gradle将执行平台的测试任务,调试器将停止在综合断点处。 同样一旦Gradle在控制台中显示browserTest任务,断点会立即触发:

此时,切换到调试器中的browserTest会话,然后选择标签为“ Debugger”的选项卡。单击“Resume Program”按钮继续执行测试:

js-debug

目前这个流程需要使IntelliJ IDEA的调试器与JS引擎保持同步。我们知道,启动调试会话的步骤比较繁琐,因此请留意之后的版本,以获取更加流畅的调试体验!

我们还计划在解决一些遗留问题后,为调试针对Node.js的Kotlin代码提供相同的体验。

文档的改进

使用Kotlin 1.3.70,我们已经对面向JavaScript的文档和教程进行了期待已久的更改,希望这让入门Kotlin/JS更加轻松。我们更新了文档并删除了过时的资料。我们还在网站上添加了一系列新的简短教程,概述了使用Kotlin/JS时可能会遇到的典型案例。它们可以辅助你开始使用Kotlin/JS Gradle插件,并且涵盖了构建面向JavaScript的应用程序时的案例。动手课程“使用React和Kotlin/JS构建Web应用程序”也已更新,现在会指导你如何为Gradle启用Kotlin/JS插件。

我们希望这些更改能让你更轻松地入门和使用Kotlin/JS,特别是如果你想尝试进行前端开发时。我们正尽力完善文档和参考资料,以帮助你学习Kotlin/JS。因此,如果你仍然觉得文档或操作方法有所欠缺,请在评论中告知我们。

Kotlin/Native

性能改进

在1.3.70中,我们准备展示在贯穿Kotlin/Native开发流程的性能优化方面所取得的初步成果。编译性能是Kotlin/Native开发中已知的劣势之一,因此我们有两个新功能可以减少编译时间:

  • 现在,Kotlin/Native编译器直接从Gradle守护程序运行,因此启动新进程以及每次编译时加载编译器都不再有时间开销了。
  • 在调试模式下,编译器将缓存项目依赖。现在,第一次编译所花费的时间会更长,但是后续编译速度将更快。请注意,目前这仅适用于iOS模拟器(iosX64)和macOS(macosX64)。同志仍需努力。
  • 我们也没有忘记改善运行时和调试的性能。在1.3.70中,我们减少了部分对象的分配时间:现在更多的对象会在栈上分配(比在堆上分配更快),并且部分单例对象会在编译时便创建了。调试过程也变得更快。

单个应用程序支持多个Kotlin框架

之前存在一个已知问题,即应用程序不能使用多个动态Kotlin/Native框架,因为来自不同的运行时实例定义的Obj-C类存在冲突。我们已经在1.3.70中修复了此问题,因此现在一个应用程序可以使用多个Kotlin/Native框架了。所有常见的依赖项都存在于框架中的不同Swift模块(以及不同的Obj-C前缀)下。

支持vector类型

从1.3.70开始,Kotlin/Native支持SIMD类型。这为Kotlin/Native提供了更多第三方API,例如流行的Apple框架AccelerateSpriteKit

脚本

1.3.70版提供了一组改进,在IntelliJ IDEA和Kotlin命令行工具中使用Kotlin脚本将有更好的体验。 另外,为了帮助你熟悉Kotlin脚本,我们准备了一个示例项目。它包含标准脚本(\* .main.kts)示例,以及脚本API用法和自定义脚本定义示例。请尝试一下,并在我们的问题跟踪器中反馈。

编译器和IDE对kotlin-main-kts的支持

在Kotlin 1.3中,我们引入了kotlin-main-kts组件,该组件简化了基础工具脚本的创建和使用。现在默认情况下,它是由Kotlin编译器和IntelliJ插件加载的,因此\* .main.kts脚本支持开箱即用。特别现在你可以使用这类脚本,而无需将kotlin-main-kts.jar添加到类路径中。 在IntelliJ IDEA中,这为* .main.kts文件(即便在源目录之外)提供了高亮和代码导航,甚至可以解析动态的依赖。 我们还通过对* .main.kts脚本进行缓存来提高执行速度,同时运行速度也大幅度提高。

命令行工具

我们还扩展了命令行工具中对Kotlin脚本的支持。 Kotlin命令行编译器附带的kotlin 运行器现在支持执行脚本。要使用kotlin运行脚本,只需给它传递脚本的文件名:

这样的调用将与使用-script配置调用编译器以完全相同的方式执行脚本。 kotlin.main.kts的识别是开箱即用的。 kotlin运行器也可以用于表达式求值。要对表达式进行求值,请将其作为参数传递给–e / -expression配置项:

你将立即获得结果。 相同的功能已添加到Kotlin命令行编译器,但有不一样的配置名:-Xexpression

如何更新

同样的,你可以在play.kotl.in使用在线Kotlin

  • Gradle或Maven:指定编译器及标准库的版本为1.3.70。参考GradleMaven的文档。
  • IntelliJ IDEAAndroid Studio:打开Tools | Kotlin | Configure Kotlin Plugin Updates然后点击“Check again”按钮,以更新Kotlin插件到1.3.70版本。
  • Eclipse:通过Marketplace安装插件。
  • 可以在Github发布页面下载命令行编译器

如果你在新版本中遇到任何问题,欢迎在Slack(在这里获得邀请)的论坛上寻求帮助,或在问题跟踪器中报告。

Let’s Kotlin!

其他贡献者

我们要感谢Fleshgrinder在为集合添加的builder函数方面所做的工作,以及adellibovi在添加reduceOrNull()函数方面所做的工作。

同样感谢提交的PR合并到该版本中的所有其他贡献者:

此条目发表在官方分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注