愛伊米

Kotlin 1.6.0 釋出,大量新特性與功能穩定

出品|開源中國

作者|羅奇奇

11 月 16 日,JetBrains釋出了 Kotlin 1。6。0 ,其中包含穩定的詳盡

whens

宣告、Kover 和 Kotlin/Native 的新記憶體管理器,1。5。30 中釋出的其他語言和標準庫功能也變得更穩定。

密封(詳盡)

Sealed

when

是一項期待已久的功能,如果你的 when 語句不夠詳盡,Kotlin 編譯器發會警告。

Kotlin 會詳盡地檢查封閉類、列舉和布林型別的表示式,使用那些代數資料型別對域建模時它非常有用。例如對應用程式的使用者有不同的契約首選項,建模為一個封閉的類層次結構:

sealed class Contact {    data class PhoneCall(val number: String) : Contact()    data class TextMessage(val number: String) : Contact()    data class InstantMessage(val type: IMType, val user: String) : Contact() }

現在,如果你寫了一個表示式:根據不同的聯絡人偏好返回不同的結果。但是又忘記處理應用程式中的所有型別,編譯器將會標記一個錯誤:

fun Rates。computeMessageCost(contact: Contact): Cost =    when (contact) { // ERROR: ‘when’ expression must be exhaustive        is Contact。PhoneCall -> phoneCallCost        is Contact。TextMessage -> textMessageCost    }

在 Kotlin 1。6。0 之前,這種問題編譯器只會報弱 IDE 檢查,從 Kotlin 1。6 開始,它會產生以下編譯器警告(warning):

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 中它會變成一個錯誤(ERROR),詳情可參閱KT-47709。

Suspending 函式作為超型別

Kotlin 1。6 穩定了對將

suspend

掛起函式型別實現為超級介面的功能。

設計 Kotlin API 需要自定義各種庫函式的行為時,接受函式型別是慣用的做法。例如,

kotlinx.coroutines

API 在其 Job 介面中有一個成員函式,看起來類似於:

fun invokeOnCompletion(handler: () -> Unit)

可以方便地使用像

invokeOnCompletion

這些 lambda 函式。如果想要處理完成的類,可以透過在類中直接實現函式 type () -> Unit 來簡化和最佳化程式碼,而不需要建立額外的 lambda 。

class MyCompletionHandler : () -> Unit {    override fun invoke() { doSomething() } }

從Kotlin 1。6開始,這種最佳化可以透過掛起函式實現。如果你的 api 接受掛起函式型別,像這樣:

public fun launchOnClick(action: suspend () -> Unit) {}

那麼我們就不再侷限於傳遞 lambda 和掛起函式引用了,也可以在類中實現相應的掛起函式型別:

class MyClickAction : suspend () -> Unit {    override suspend fun invoke() { doSomething() } }

掛起轉換

Kotlin 1。6 穩定了從常規到掛起函式型別的轉換。現在可以傳遞任何常規函式型別的表示式,其中使用預期掛起作為引數,編譯器將自動執行轉換。

改進了遞迴泛型型別的型別推斷

從1。6。0開始,如果預設情況下是遞迴泛型,Kotlin編譯器能根據相應型別形參的上限推斷型別實參。這可以實現使用遞迴泛型型別建立各種模式(通常在 Java 中用於製作構建器 API):

// Before 1。5。30 val containerA = PostgreSQLContainer(DockerImageName。parse(“postgres:13-alpine”))。apply {     withDatabaseName(“db”)     withUsername(“user”)     withPassword(“password”)     withInitScript(“sql/schema。sql”) } // With compiler option in 1。5。30 or by default starting with 1。6。0 val containerB = PostgreSQLContainer(DockerImageName。parse(“postgres:13-alpine”))     。withDatabaseName(“db”)     。withUsername(“user”)     。withPassword(“password”)     。withInitScript(“sql/schema。sql”)

Builder inference 改進

Kotlin 1。5。30 引入了

-Xunrestricted-builder-inference

編譯器選項,讓關於構建器呼叫的型別資訊可以在構建器 lambda 中獲取。也就是說,它引入了呼叫返回尚未推斷型別的例項的能力,比如 buildList() lambda 中的

get()

從 1。6。0 開始,無需指定

-Xunrestricted-builder-inference

進行以前禁止的呼叫。現在可以使用-Xenable-builder-inference 編譯器選項編寫自己的泛型構建器,而不需要應用

@BuilderInference

註釋,且如果常規型別推斷無法解析型別資訊,你還可以自動啟用 Builder inference構建器推斷。

長期支援以前的 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 記憶體管理器

的實驗版。此功能致力於在多平臺專案中提供一致的開發體驗。新的記憶體管理器解除了對執行緒間物件共享的現有限制,並提供完全無洩漏的併發程式設計原語,這些原語是安全的,不需要開發人員進行任何特殊管理或註釋。

Kotlin/Native 現在支援 Xcode 13。

在任何主機上編譯 Windows 目標,

現在可以在任何支援 Kotlin/Native 的主機上編譯 Windows 目標

mingwX64

mingwX86

Kotlin 1。6。0

重新設計了

Kotlin/Native 在幕後使用

的 LLVM 依賴項,

同時將 LLVM 版本更新到 11。1。0 ,並減少了依賴項大小。

帶有 JVM 和 JS IR 後端的統一編譯器外掛 ABI

。現在,Kotlin 多平臺 Gradle 外掛能夠將可嵌入的編譯器 jar(用於 JVM 和 JS IR 後端的那個)用於 Kotlin/Native,這意味著可以為 Native 和其他支援的平臺使用相同的編譯器外掛工件。

穩定的

Kotlin 1。6。0 帶來了穩定的

typeOf()

。從 1。3。40 開始,

typeOf()

作為實驗性 API 在 JVM 平臺上可用,現在可以在任何 Kotlin 平臺上使用它,且

KType

編譯器可以推斷任何 Kotlin 型別的表示。

inline fun  renderType(): String {     val type = typeOf()     return type。toString() } fun main() {     val fromExplicitType = typeOf()     val fromReifiedType = renderType>() }

穩定的集合構建器

buildMap()

buildList()

buildSet()

已經穩定,構建器返回的集合現在可以在只讀狀態下序列化。

穩定的整數位旋轉操作

將數字的二進位制表示式向左或向右旋轉指定位數的

rotateLeft()

rotateRight()

函式已經穩定。

val number: Short = 0b10001 println(number。rotateRight(2)。toString(radix = 2)) // 100000000000100 println(number。rotateLeft(2)。toString(radix = 2))  // 1000100

穩定正則表示式函式

穩定了

splitToSequence()

——一個用於將字串拆分為序列的正則表示式函式

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”

有關 Kotlin 1。6。0 的詳盡資訊可在釋出公告中檢視。

Kotlin 1.6.0 釋出,大量新特性與功能穩定