Kotlin 1.6.0 新特性预览:语法和标准库

Posted 东海陈光剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 1.6.0 新特性预览:语法和标准库相关的知识,希望对你有一定的参考价值。

Kotlin 1.5.30 is the last incremental release before Kotlin 1.6.0, it includes many experimental language and standard library features that we are planning to release in Kotlin 1.6.0:

  1. sealed when statements

  2. opt-in requirements

  3. instantiation of annotation classes

  4. Duration and Regex stdlib APIs, and more.

The Kotlin roadmap includes adding support for sealed when statements, releasing opt-in annotations, improving type inference, and stabilizing builder inference. 

Kotlin 1.5.30 takes a step down this road by providing a preview of these features, whose release is planned for 1.6.0.

Sealed when statements

Sealed when is a long awaited feature with more than 280 votes in YouTrack. If you enable this feature in 1.5.30, the Kotlin compiler will warn if one of your when statements is not exhaustive. This will make your code safer without you having to introduce your own functions.

Give this feature a try and provide your feedback in this YouTrack ticket. 

Support for suspend functions as supertypes

Kotlin 1.5.30 provides a preview of an ability to use suspend functional types as super interfaces, although it has some limitations. It’s one of the missing pieces in the Kotlin coroutines design.

class MyClass: suspend () -> Unit {
    override suspend fun invoke() { TODO() }
}

Changes to opt-in requirements

As a further step toward the release of opt-in annotations, Kotlin 1.5.30:

  • Presents new rules for using and declaring opt-in requirement annotations on different targets. 

  • Requires opt-in even for implicit usages of an experimental API. For example, if the function’s return type is marked as an experimental API element, a usage of the function requires you to opt-in even if the declaration is not marked as requiring an opt-in explicitly.

// Library code


@RequiresOptIn(message = "This API is experimental.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
annotation class MyDateTime // Opt-in requirement annotation


@MyDateTime
class DateProvider // A class requiring opt-in


// Client code


// Warning: experimental API usage
fun createDateSource(): DateProvider { /* ... */ }


fun getDate(): Date {
    val dateSource = createDateSource() // Also warning: experimental API usage
    // ...
}

Improvements to type inference on recursive generic types 

With type inference on recursive generic types enabled, the Kotlin 1.5.30 compiler can infer a type argument based only on the upper bounds of the corresponding type parameter if it is a recursive generic. This makes it possible to create various patterns with recursive generic types that are often used in Java to make builder APIs.

// Kotlin 1.5.20
val containerA = PostgreSQLContainer<Nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
    withDatabaseName("db")
    withUsername("user")
    withPassword("password")
    withInitScript("sql/schema.sql")
}


// Kotlin 1.5.30
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
    .withDatabaseName("db")
    .withUsername("user")
    .withPassword("password")
    .withInitScript("sql/schema.sql")

Eliminating builder inference restrictions 

With eliminating builder inference restrictions enabled, Kotlin 1.5.30 removes a builder inference restriction. Not only can you specify the type information that builder inference can infer, but you can also use the get function on it. For example, you can call get() inside a lambda argument of buildList() without explicitly specified type arguments.

Kotlin Multiplatform

Kotlin 1.5.30 includes the following improvements for Kotlin Multiplatform:

  • Ability to use custom cinterop libraries in shared native code, which extends the ability to share platform-dependent libraries shipped with Kotlin/Native. 

  • Support for XCFrameworks as an output format for all Kotlin Multiplatform projects. XCFrameworks help gather logic for all the target platforms and architectures in a single bundle and don’t require removing unnecessary architectures before publishing the application to AppStore.

  • New default publishing setup for android artifacts. This setup will be compatible with any build type (like debug or release)  by default. Before 1.5.30, the metadata generated by the maven-publish Gradle plugin when publishing a multiplatform library for Android included the build type attribute for every published Android variant. This made it compatible only with the same build type used by the library consumer. 

Kotlin/JVM

With Kotlin 1.5.30, Kotlin/JVM gets the following updates:

  • Improved nullability annotation support configuration. You can specify whether the compiler reports a nullability mismatch based on information from specific types of nullability annotations. Learn how to enable this improvement and see the full list of supported nullability annotations, which has been extended with RxJava3 annotations. 

  • Instantiation of annotation classes. If you enable this feature, you can call constructors of annotation classes in arbitrary code to obtain a resulting instance. This feature covers the same use cases as the Java convention, which enables the implementation of an annotation interface. Learn more about instantiation of annotation classes in this KEEP.

annotation class InfoMarker(val info: String)


fun processInfo(marker: InfoMarker) = ...


fun main(args: Array<String>) {
    if (args.size != 0)
        processInfo(getAnnotationReflective(args))
    else
        processInfo(InfoMarker("default"))
}

Kotlin/Native

Kotlin 1.5.30 provides the following improvements for Kotlin/Native:

  • Native support for Apple silicon. You can now build applications on Apple silicon hardware for all targets that are supported on Intel-based Macs, without having to use the Rosetta translation environment. New targets introduced in 1.5.30 – macosArm64, iosSimulatorArm64, watchosSimulatorArm64, and tvosSimulatorArm64 – make it possible to run Kotlin code on Apple silicon natively. 

  • Improved Kotlin DSL for the CocoaPods Gradle plugin. Kotlin 1.5.30 improves CocoaPods configuration by providing a new DSL format for frameworks that is identical to a framework definition for Apple targets. You can define whether it is a static or dynamic type, enable the explicit export of dependencies and the Bitcode embedding, and configure other options.

  • Experimental interoperability with Swift 5.5 async/await. Learn more about the current state of Swift 5.5 interoperability and leave your feedback in this YouTrack issue.

  • Deprecation of linkage to DLLs without import libraries for MinGW (Windows). This deprecation is the result of the switch to the LLD linker, which has better performance and other improvements. Feel free to share your thoughts and concerns about the transition to the LLD linker in this YouTrack issue.

  • Improved Swift/Objective-C mapping for objects and companion objects. Now you can access objects and companion objects in a way that’s more intuitive for native iOS developers – using the .shared and .companion properties. 

Kotlin/JS

Kotlin 1.5.30 provides the following improvements for Kotlin/JS:

  • JS IR compiler backend reaches Beta. To simplify migration to the new backend, you can use the migration guide and the new Kotlin/JS Inspection Pack IDE plugin, which guides you through the process of making the necessary changes directly in IntelliJ IDEA.

  • A better debugging experience for applications with the Kotlin/JS IR backend, thanks to javascript source map generation. Now you can benefit from support for breakpoints, stepping, and readable stack traces with proper source references in any JavaScript debugger. Learn more about debugging Kotlin/JS applications.

Gradle

Kotlin 1.5.30 introduces the following features to improve the Kotlin Gradle plugin user experience:

  • Support for Java toolchains. Gradle 6.7 introduced support for Java toolchains, which make it easy to select a JDK for project compilation. Just declare the version you need in the build script and Gradle does the rest, finding it on your host machine or even downloading and installing it if it’s not there yet. The Kotlin Gradle plugin supports Java toolchains for Kotlin/JVM compilation tasks. For Gradle versions 6.1-6.6, set a JDK home with the UsesKotlinJavaToolchain interface.

  • Easier ways to explicitly specify Kotlin daemon JVM arguments. If nothing is specified for the Kotlin daemon, it inherits arguments from the Gradle daemon. You can now also specify arguments for a specific task, as well as for the Kotlin extension, as a single line in build.gradle.kts or gradle.properties.

build.gradle.kts

kotlin {
    kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
}

gradle.properties

kotlin.daemon.jvmargs = -Xmx486m -Xms256m -XX:+UseParallelGC

Standard library

Kotlin 1.5.30 brings improvements to the standard library’s Duration and Regex APIs:

Duration API improvements

As indicated in our libraries roadmap, we’re going to stabilize the Duration API in Kotlin 1.6.0, which means this is the last chance to give it a try and share your feedback with us on anything you’d like changed. We would appreciate your feedback in this KEEP.

Kotlin 1.5.30 provides a preview of API improvements. The output of Duration.toString() is now more readable. For example, Duration.minutes(920).toString() produces 15h 20m instead of the previous 920m.

A negative duration is now prefixed with a minus sign (-), and it is surrounded by parentheses if it consists of multiple components: -12m and -(1h 30m).

This release also provides a preview of new functions for parsing Duration from String:

  • parse() parses Duration objects from strings formatted as Duration’s toString() or from strings representing ISO 8601 durations (such as toIsoString() outputs).

  • parseIsoString() parses Duration objects from strings representing ISO 8601 durations.

  • *OrNull() counterparts for both functions.

val isoFormatString = "PT1H30M"
val defaultFormatString = "1h 30m"
println(Duration.parse(isoFormatString)) // "1h 30m"
println(Duration.parse(defaultFormatString)) // "1h 30m"
Target platform: JVMRunning on kotlin v.1.5.31

Regex API improvements

Kotlin 1.5.30 provides new experimental functions for regular expressions:

  • matchesAt() checks whether a regex has a match in the specified position of a String.

  • matchAt() returns the match if one is found.

val releaseText = "Kotlin 1.5.30 is released!"
val versionRegex = "\\\\d[.]\\\\d[.]\\\\d+".toRegex()
println(versionRegex.matchAt(releaseText, 0)) // "null"
println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"
Target platform: JVMRunning on kotlin v.1.5.31
splitToSequence() is a lazy counterpart of split(). It splits the string around matches of the given regex, but returns the result as a Sequence. A similar function has also been added to CharSequence.




val colorsText = "green, red , brown&blue, orange, pink&green"
val regex = "[,\\\\s]+".toRegex()
val mixedColor = regex.splitToSequence(colorsText)
    .onEach { println(it) }
    .firstOrNull { it.contains('&') }
println(mixedColor) // "brown&blue"
Target platform: JVMRunning on kotlin v.1.5.31

How to install Kotlin 1.5.30

If you already use IntelliJ IDEA or Android Studio, your IDE will suggest updating Kotlin to 1.5.30 automatically. You can also update manually by following these instructions. 

You can download the latest versions of these IDEs to get extensive support for Kotlin:

  • IntelliJ IDEA – for developing Kotlin applications for various platforms.

  • Android Studio –  for developing Android and cross-platform mobile applications.

Make sure that you have also updated the kotlinx libraries to compatible versions and specified version 1.5.30 of Kotlin in the build scripts of your existing projects.

If you need the command-line compiler, download it from the Github release page.


☞  关于 Kotlin 编程的书籍推荐:

以上是关于Kotlin 1.6.0 新特性预览:语法和标准库的主要内容,如果未能解决你的问题,请参考以下文章

Swift5 新特性预览

C++基础C++11的新特性

kotlin—lazy及其原理

C# 9.0 新特性预览

官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?

Kotlin学习与实践 基础