Kotlin 1.4-M3带着标准库改动来了!

今天,很高兴迎来最后一个里程碑预览版Kotlin 1.4–1.4-M3。在这篇博客中,我们将引导你了解该预览版带给Kotlin标准库的更改。其他组件也在M3中得到更新。我们将在另一篇博客介绍候选版本(1.4-RC),以最终敲定Kotlin 1.4。

img

1.4-M3中标准库的变动如下:

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

如果你能尝试预览版向我们反馈,我们将不胜感激。

标准库工件已包含模块修饰符

从Java 9开始,得益于Jigsaw项目,你可以将应用程序模块化。通过jlink工具,你可以创建一个自定义Java运行时镜像,该镜像仅包括应用程序所需的平台模块。之前你可以同时使用jlink和Kotlin标准库工件,但为此必须使用单独带有“模块化”分类器的工件——并且整个配置并不容易。无法在主要工件中包含模块修饰符是Android工具引起的,现在该问题已得以修复。

Kotlin 1.4将module-info.java模块信息添加到默认的标准库构件中,因此它们能轻松地与jlink结合使用。在Android中,请确保使用3.2以及更高版本的Android Gradle插件,该插件能正确处理带有模块修饰符的jar包。

标准库中的函数式接口

Kotlin 1.4支持Kotlin类的SAM转换。你可以将仅有一个抽象方法的接口标记为fun interface,便可向参数类型为此接口的方法传递lammbda。在标准库中,以下接口现已声明为fun interface

  • Comparator
  • ReadOnlyProperty
  • PropertyDelegateProvider(在1.4-M2引入)

你可以通过以lambda作为参数的SAM构造函数来创建实例。这会让代码变得更加简洁:

img

集合操作

新增一个sumOf函数,其接受一个selector函数,并返回集合所有元素上的值的总和。它与现有的sumBysumByDouble函数非常相似。关键区别在于新sumOf的selector函数支持多种数据类型,从而能以同一种方式求取不同数据类型的总和。sumOf可以给类型为IntLongDoubleUIntULong求和。在JVM上还可作用于BigIntegerBigDecimal

  • minmax函数已重命名为minOrNullmaxOrNull。自1.0版引入以来,空集的minmax会返回null。这不符合Kotlin集合API中的命名规范:如果接收者集合为空,则没有*OrNull后缀的函数会引发异常。要得到null,请使用函数的*OrNull版本,例如firstOrNull。 因此,我们决定逐渐改变minmax的行为。在1.4-M3中,我们将minOrNullmaxOrNull添加为minmax的同义词,并开始minmax的弃用周期,以使用非null返回类型重新引入它们。
  • 我们引入了minOfmaxOf函数,它们将返回selector函数所作用集合的最小值或最大值。这些函数可覆盖map { selector }.max()!!maxBy { selector }!!.selector(或minminBy)的场景。

为了与现有API保持一致,我们还添加了minOfWithmaxOfWith,它们均以Comparator作为参数。 所有的这四个新函数都遵循我们上面描述的非null规范:它们在空集上引发异常,并且具有* orNull版本,在这种情况下将返回null。

  • flatMapflatMapTo的新重载可以在返回类型与接收类型不匹配时进行转换,即:
    • IterableArrayMap转换为Sequence
      • Sequence转换为Iterable
  • 新增了flatMapIndexed函数作为flatMap的配对函数。你可能已知道,集合处理函数的名称中有Indexed意味着操作函数会带有一个索引参数。

通用@Throws注解

尽管Kotlin没有受检查异常,但通过@Throws注解 可和有此规范的语言(如Java和Swift)互操作。此前对于JVM(kotlin.jvm.Throws)和Native(kotlin.native.Throws),分别采取了不同名称进行了注解。从1.4-M3开始,@ Throws注解将直接作为kotlin包(kotlin.Throws)公共库的一部分,并可在公共代码中使用。

Swift和Objective-C中挂起函数的@Throws

在1.4-M1中,我们公布了Objective-C/Swift互操作中异常处理方面的变动:现在,NSError仅引发@Throws注解(或其子类)参数的类实例的异常。在1.4-M2中,我们引入了对Swift和Objective-C中Kotlin挂起函数的基本支持。在1.4-M3,被@Throws注解的挂起函数的行为会有微小的变化:

  • 如果你使用@Throws注解了suspend fun,则需要指定CancellationException :: class作为@Throws注解的参数。否则,编译将报错。
  • 如果suspend fun上没有@Throws注解,在Swift调用时,它将隐式使用@Throws(CancellationException :: class)

浮点数组中的Equality

很多人都知道这些方便的容器类型扩展函数—containsindexOflastIndexOf。不久之前,我们发现它们在浮点数组(FloatArrayDoubleArray)上的行为可能存在争议,并且看起来可能不正确。 具体来说,它们使用IEEE 754标准进行浮点运算。该标准为极端情况定义了以下判等规则:

  • NaN 不等于 NaN
  • -0.0 等于 0.0

这些规则可能会导致意外的结果,例如:

另外,其行为与相同函数在列表上的结果不一致,因为它们采取了total order相等:

在1.4-M3中,我们开始了FloatArrayDoubleArraycontainsindexOflastIndexOf扩展函数的弃用周期。当你使用它们时,会看到警告以及有关这些函数代替用法的说明。 在未来的版本中,我们会将弃用级别提高到ERROR,并从公共API中删除这些函数。

KType转换为Java Type

在Kotlin 1.3.40,我们向标准库添加了一个有用的typeOf函数。该函数返回给定泛型T的运行时表示形式作为KType的实例。但是在许多实际场景中,你需要Java反射的[java.lang.reflect.Type]对象(https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Type.html),而非KTypes。尽管可以转换,但这需要完整的kotlin-reflect依赖。而现在我们更新了标准库,将KType转换为Java Type—一个返回Java TypeKType.javaType扩展属性:

请注意,到目前为止,所获取的Java类型在某些特殊情况下(例如带注解的类型参数或declaration-site variance)无法正常运行,因此KType.javaType仍处于试验阶段。你可以在该issue中查看更多未被支持场景的详细信息。

兼容性

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

正式发布前注意事项

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

如何尝试最新的特性

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

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

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

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

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

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

分享你的反馈

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

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

Let’s Kotlin!

其他贡献者

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

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

发表评论

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