Kotlin 1.4-M2正式发布

时光飞逝,今天我们想向你展示Kotlin 1.4的部分强大的预览特性。在Kotlin 1.4正式发布之前,请了解并尝试Kotlin 1.4-M2。

kotlin-1.4-M2

我们很感谢试用了Kotlin 1.4首个预览版并反馈以帮助Kotlin变得更完善的人!

也非常感谢尝试了在上一篇博文所提到的*Kotlin 1.4-M2’s标准库的改动的人。

在这篇博文中,我们将重点介绍1.4-M2中可用的新特性和关键改进:

你可以在更新日志中找到完整的变更列表。我们同样非常感谢其他贡献者

如果你能尝试预览版反馈,我们将非常感激。

多目标分层项目架构中共享代码

随着项目分层架构的支持,你可以在多平台项目的多个目标中共享代码。

在此之前,多平台项目中的代码要么被放入到平台的指定源集中(仅限于一个目标,并且不能被任何其他平台复用),要么放入到公共源集中,例如commonMaincommonTest,在项目中的所有平台之间共享。在公共源集中,你只能调用被expect声明的平台独立实现的actualAPI。

虽然这让在所有目标之间共享代码变得容易,但是在目标之间的共享却并不容易,尤其复用通用逻辑和第三方API的相似目标。

例如,在针对iOS的典型多平台项目中,有两个与iOS相关的目标:一个针对iOS ARM64设备,另一个针对x64模拟器。它们具有独立的平台指定的源集,但是在实践中,几乎不需要为设备和模拟器使用不同的代码,并且它们的依赖非常相似。因此可以在它们之间共享iOS平台特定的代码。

显然,在此设置中,希望能有两个iOS目标的共享源集,并且Kotlin/Native代码仍可以直接调用iOS设备和模拟器共通的任何API。

ios-source-sets

现在你可以在分层项目架构来实现这一点,它会根据调用方的目标来推断和调整每个源集中可用的API和语言功能。

如何使用

Install the 1.4 M2 Kotlin plugin with the hierarchical project support right now!

在你的项目gradle.properties文件中加入以下配置项:

请注意,从Kotlin 1.4-M2开始,层次架构以及所有多平台项目都需要Gradle 6.0及更高版本。

你可以通过应用于典型场景的多目标快捷方式创建层次架构,也可以通过连接源集来手动创建层次架构。

例如,使用ios()快捷方式创建两个iOS目标以及上述所展示的共享源集:

至于其他目标的组合,通过将源集与dependsOn连接来手动创建层次结构。

你可以为以下目标组合设置共享源集:

  • JVM + JS + Native
  • JVM + Native
  • JS + Native
  • JVM + JS
  • Native

当前,我们不支持为以下目标组合共享源集:

  • Several JVM targets
  • JVM + Android targets
  • Several JS targets

请随时通过发送电子邮件至feedback@kotlinlang.org与我们分享你的目标组合。这将有助于我们优先考虑更常用的组合。

库中的共享代码

归功于分层项目架构,库还可以为目标子集提供通用API。

库被发布时,其共享源集的API连同相关项目结构的信息将被嵌入到库工件中。使用该库时,项目的共享源集将能精确获取到各个源集可用于目标的库API。

例如,请检出并了解kotlinx.coroutines存储库的native-mt分支下的源集层次结构:

并发源集声明了函数runBlocking并针对JVM和Native目标进行编译。你可以在面向JVM及Native的目标中依赖并调用runBlocking(),您可以依赖它,并从JVM目标和本机目标之间共享的源集中调用runBlocking(),因为它会匹配库的concurrent源集中的“目标签名”。

只需要指定一次依赖

从现在开始,不需要在共享和平台相关的源集中对同一库指定不同变体的依赖,而应该在共享源集中仅指定一次依赖关系。

不要使用有特定平台后缀的kotlinx库工件名称,例如-common-**native**或类似名称,因为它们已不再受支持。请使用库的基本工件名称取而代之,在上面的示例中,其名称为kotlinx-coroutines-core。但是这个更改目前不影响stdlibkotlin.test库(stdlib-commontest-common);它们被安排在之后。

如果只需要特定平台的依赖,则仍然可以使用标准库和kotlinx库的平台特定变体,后缀为-jvm-js,例如kotlinx-coroutines-core-jvm

在分层结构中使用native库

你可以在多个native目标之间共享的源集中使用平台相关的库,例如FoundationUIKitposix。这可以帮助你共享更多的native代码,而不受平台特定的依赖限制。

无需任何步骤,这一切都会自动完成。 IntelliJ IDEA将帮助你检测可在共享代码中使用的通用声明。

但是请注意,存在一些限制:

  • 该方法仅适用于共享给平台特定源集之间的native源集。而不适用于共享给更高层级源集的native源集。
  • 例如,如果你有一个nativeDarwinMain,它是watchosMainiosMain的父级,其中iosMain有两个子级iosArm64MainiosX64Main,则平台相关的库只能用于iosMain,而不能用于nativeDarwinMain
  • 该方法仅适用于Kotlin/Native定制的互操作库。

详细了解更多技术细节.

如何使用

要在共享源集中启用平台相关库,请将以下内容添加到gradle.properties中:

分享分层架构的反馈

请注意,分层项目结构目前处于技术预览阶段,并且仍在开发中。你可以查看我们将要解决的已知问题,其中一些已有解决方案。

欢迎在Kotlin Slack的#multiplatform频道中寻求帮助,并将错误报告给我们的问题跟踪器 YouTrack。这是一项复杂而重要的特性,因此你的反馈将特别有用!

多平台项目中要求Gradle 6.0或更高版本

从Kotlin 1.4-M2开始,所有多平台项目将要求Gradle版本为6.0及以上。请确保为用到kotlin-multiplatform插件的项目升级Gradle。

更灵活的项目向导

通过使用新的更灵活的Kotlin项目向导,你可以在同一个地方轻松地创建和配置不同类型的Kotlin项目,包括多平台项目,这在没有UI的旧版本是难以想象的。

project-wizard-1

以前,你可以从不同位置提供不同的配置来创建Kotlin项目。现在只有一个地方可以做到这一点,它保证了简洁而又不失灵活:

  1. 选择项目模板,具体取决于你要执行的操作。
  2. 选择构建系统——Gradle(Kotlin或Groovy DSL),Maven或IntelliJ。该向导仅显示所选项目模板支持的构建系统。
  3. 在主界面上预览项目结构

然后,你可以完成创建项目,或者(可选)在下一个界面上配置项目

  1. 添加/删除项目模板所支持的模块和目标
  2. 配置模块和目标设置,例如目标JVM版本,目标模板和测试框架。
project-wizard-2
  1. 设置模板间的依赖关系
    • iOS和多平台模块
    • Android和多平台模块
    • JVM模块
project-wizard-3

未来我们将通过添加更多配置选项和模板来使Kotlin项目向导更为灵活。

如何使用

  1. 安装1.4-M2 Kotlin插件
  2. 在IntelliJ IDEA中点击File | New | Project
  3. 在左侧的面板中选择Kotlin (Experimental Wizard)
  4. 创建你的新Kotlin项目。

显式API模式:统一且描述清晰的API

我们正在引入一种新的编译器模式,以帮助库作者创建一致且描述良好的API。在这种显式的API模式下,编译器会对库的公共API声明进行额外的检查:

  • 如果是默认可见性公开的公共API,则(API)声明必须包含可见性修饰符。这有助于确保不会在无意间公开为public。
  • 对于public API公开的属性和函数,需要明确其类型。这样可以确保API的用户知道他们要用到的API成员类型。
explicity-api-mode

根据你的配置,检查后会发出错误(strict 模式)或警告(warning模式)。

我们计划将来增加更多检查,以改善你编写代码库的体验。你可以在KEEP中了解有关的更多信息。但是你已经可以尝试显式API模式并与我们分享你的反馈。

要在显式API模式下编译模块,请在Gradle构建脚本中添加以下配置:

kotlin { explicitApi() // for strict mode // or explicitApiWarning() // for warning mode }

在Groovy中,你可以使用这样的语法:

当使用命令行编译器时,请在-Xexplicit-api编译器选项中使用strictwarning

Kotlin/Native支持挂起函数及其他改进

在该预览中,Kotlin终于支持Swift和Objective-C中的挂起函数了,目前仅涵盖了基本场景。我们一直在努力为Swift和Objective-C应用程序提供协程的完整功能。除此之外,我们准备介绍Kotlin/Native的性能及稳定性方面的一些工作成果。

Kotlin支持Swift和Objective-C的挂起函数

我们将继续扩展Swift和Objective-C代码中对Kotlin关键功能的支持。之前版本已知的其中一个缺点是它们不完全支持Kotlin协程:没有为Swift或Objective-C代码提供挂起函数。

在M2预览中,我们很高兴为Swift和Objective-C中的挂起函数提供了基本支持。现在,当你将Kotlin模块编译成Apple框架时,其中的挂起函数可以作为带有回调的函数使用(Swift/Objective-C术语中的completionHandler)。如果在生成的框架头文件中具有此类函数,则你可以在Swift或Objective-C代码中调用它们,甚至重写它们。

例如,当你编写这样一个Kotlin函数:

…然后你可以在Swift上如此调用:

请注意在M2预览中,你只能在主线程中调用挂起函数。

通过gutter图标运行Kotlin/Native代码

之前你只能在Terminal中运行Kotlin/Native代码,也可以在IntelliJ IDEA中通过Gradle任务运行。而现在,你可以方便地使用gutter图标去运行,就像其他Kotlin代码一样。

native-gutter-icon

C互操作性的性能改进

在提高Kotlin/Native性能的范围内,我们重新设计了C互操作库的构建方式。 (这些库是允许你在Kotlin代码中使用C和Objective-C库声明的工件。)这些变化虽然是肉眼不可见的,但可以感受到性能的提高和工件体积的减小:新工具的生成速度是以前的4倍,工件的大小是以前的25%到30%!

使用interop库现在也更快,因为在Kotlin 1.4-M2用C interop编译Kotlin项目花费的时间更少。

更稳定的编译器缓存和启用Gradle守护进程

在1.3.70中,我们引入了两个新功能来提高Kotlin/Native的编译性能: 缓存项目依赖在Gradle守护进程中运行编译。这些仍在完善中,因此部分情况下可能会遇到不稳定的问题。

感谢你们的反馈,我们已设法解决了许多问题并提高了这些功能的整体稳定性。因此,如果你遇到了问题,或者没有机会尝试最新版本的Kotlin/Native,现在可以尝试一下了。

Kotlin/JS的改进

在1.4-M2中,Kotlin针对JavaScript目标的Gradle命名规范与其他Kotlin目标的规范更加相似了。它还默认增加了对编译器设置更细粒度的控制,@JsExport注解通用化,以及通过webpack启用了CSS支持。

Gradle DSL的变动

命名变更

为了与其他Kotlin目标更加匹配,我们改动了Kotlin/JS Gradle一些常用配置的名称。而对于1.4-M2中Kotlin/JS Gradle项目的默认配置块,以下说明了我们所做的两个命名更改:

  • target变更为js,这与Kotlin多平台插件的语法一致。
  • Kotlin 1.4-M1中引入的produceExecutable()变更为binaries.executable(),使其与Kotlin/Native的命名一致。

如果你想进一步了解binaries.executable()的功能,请参阅1.4-M1博文的“ Kotlin/JS | Gradle DSL的变化”。

各个项目的编译设置

Kotlin 1.4-M1,我们首先引入的新IR编译器后端,具有DCE优化,TypeScript声明预览等功能,其中包含一个在gradle.properties中的设置,可在默认,IR和同时启用的编译器模式之间切换。 M2直接从Gradle配置中引入了对每个项目所使用的编译器模式更细粒度的控制。

要在不同的编译器模式之间切换,请将编译器类型传递给Gradle构建脚本的js函数。例如:

像这样为项目设置的编译器类型会覆盖gradle.properties中指定的默认设置。

Gradle支持Webpack的CSS加载器

由于Kotlin/JS Gradle插件默认情况下使用webpack为浏览器创建构件,因此可以自定义许多设置。虽然可以直接修改用于构建项目的webpack配置文件来更改所有选项,但我们希望能通过Gradle DSL直接访问最常用的设置项。

Kotlin 1.4-M2默认为针对浏览器的项目启用webpack的css-loader。这意味着,在大多数情况下,无需任何其他配置即可添加CSS和包含样式表的依赖到项目中。以前,你可能会遇到诸如Module parse failed: Unexpected character '@' (14:0)之类的错误。

如果要调整CSS集成的行为,可以通过js.browser.webpackTask.cssSettings进行调整。

通过cssSettings.enabled,你可以决定项目是否启用css-loader(默认情况下启用)。

通过cssSettings.mode,可以指定遇到CSS时的行为。其候选值如下:

  • "inline" (默认):样式将被添加到全局<style>标记中。
  • "extract":样式将被提取到单独的文件。然后可以被包含在HTML页面中。
  • "import":样式作为字符串处理。如果你需要在代码中访问CSS(例如val styles = require("main.css")),这将很有用。

如果要对同一项目使用不同的模式,则可以使用cssSettings.rules。在这里,你可以指定一个KotlinWebpackCssRules列表,每个列表定义一个模式以及包含和排除的规则。如果你想了解更多有关这些模式的信息,请查阅webpack文档中的包含排除规则。

自定义模块名

现在,你可以直接在Gradle构建脚本中改变JavaScript的模块名称:

这将影响到在build/js/packages/myModuleName中生成的模块名称,包括相关的.js.d.ts文件名。请注意,这不会影响Webpack在build/distributions中的输出。要更改webpacked文件的名称,可以使用js.browser.webpackTask.outputFileName

通用代码的@JsExport注解

@JsExport注解现可在通用代码中使用,该注解在IR编译器后端启用时从JavaScript或TypeScript中生成顶级声明。这避免了引入自定义注解和类型别名,并铺平了多平台Kotlin项目更便捷构建JavaScript库的道路。

其他体验改进及重要修复

  • 用于浏览器和nodejs目标的常规Gradle任务现被划分到单独的任务组中。当通过./gradlew tasks --all列出所有任务时,kotlin browserkotlin node组将被显示到IntelliJ IDEA的Gradle工具窗口中。
  • 现在,在为node.js目标运行测试时,调试器可以正确地在断点处停止了。
  • 对于同时使用两种编译模式的项目和库,现在能正确处理klib的依赖了。

兼容性

请注意,在某些极端情况下,Kotlin 1.4不向后兼容1.3。语言委员会仔细审查了所有此类情况,并将其列入“兼容性指南”(类似于这个)。当前你可以在YouTrack中找到这份列表。

正式发布前注意事项

请注意,向后兼容性不保证包含预发行版本。其特性和API可能在后续版本中更改。当到达最终RC时,编译器将禁止所有预发行版本产生的二进制文件,并且将需要你重新编译1.4‑Mx编译过的所有内容。

如何尝试最新的特性

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

IntelliJ IDEAAndroid Studio,你可以更新Kotlin插件到1.4-M2版本。操作指南

如果要在现有项目使用预览版,则需要在Gradle或Maven中为预览版本配置构建.

你可以在Github发行页下载命令行编译器

你可以使用随版本发行的的以下版本:

这里查看有关发行版的更多细节和兼容库列表。

分享你的反馈

如果你发现错误并向我们的问题跟踪器进行报告,我们表示非常感谢。我们尝试在最终发行版前解决所有重要问题,这意味着无需等到下一个Kotlin发行版你的问题便能得到解决。

如果你有任何疑问并想参与讨论,欢迎加入Kotlin Slack (在这里获得邀请)的#eap频道。在该频道中,你还可以获取有关新预览版的通知。

Let’s Kotlin!

其他贡献者

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

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

2 则回应给 Kotlin 1.4-M2正式发布

  1. Pingback引用通告: Kotlin 1.4-M3带着新的标准库来了! - KotlinCn

  2. Pingback引用通告: Kotlin 1.4.0-RC! - KotlinCn

发表评论

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