跳至主要内容

Kotlin 1.5.20 的新特性

已發布:2021 年 6 月 24 日

Kotlin 1.5.20 修復了在 1.5.0 新功能中發現的問題,並且還包含各種工具改進。

你可以在發布部落格文章和此影片中找到變更的概述:

Kotlin/JVM

Kotlin 1.5.20 在 JVM 平台上收到了以下更新:

透過 invokedynamic 進行字串串連

Kotlin 1.5.20 將字串串連編譯為 JVM 9+ 目標上的動態調用 (invokedynamic),從而跟上現代 Java 版本。 更精確地說,它使用 StringConcatFactory.makeConcatWithConstants() 進行字串串連。

若要切換回透過 StringBuilder.append() 進行串連,該串連在先前的版本中使用,請新增編譯器選項 -Xstring-concat=inline

了解如何在 GradleMaven命令行編譯器中新增編譯器選項。

支援 JSpecify 空值註解

Kotlin 編譯器可以讀取各種類型的空值註解以將空值資訊從 Java 傳遞到 Kotlin。 1.5.20 版本引入了對 JSpecify 專案的支援, 其中包括標準的統一 Java 空值註解集。

使用 JSpecify,你可以提供更詳細的空值資訊,以幫助 Kotlin 保持與 Java 之間的空值安全互操作。 你可以為宣告、套件或模組範圍設定預設空值,指定參數化空值等等。 你可以在 JSpecify 使用者指南中找到有關此的更多詳細資訊。

以下是 Kotlin 如何處理 JSpecify 註解的範例:

// JavaClass.java
import org.jspecify.nullness.*;

@NullMarked
public class JavaClass {
public String notNullableString() { return ""; }
public @Nullable String nullableString() { return ""; }
}
// Test.kt
fun kotlinFun() = with(JavaClass()) {
notNullableString().length // OK
nullableString().length // Warning: receiver nullability mismatch
}

在 1.5.20 中,根據 JSpecify 提供的空值資訊的所有空值不符都會報告為警告。 使用 -Xjspecify-annotations=strict-Xtype-enhancement-improvements-strict-mode 編譯器選項來啟用嚴格模式(具有錯誤報告)以使用 JSpecify。 請注意,JSpecify 專案正在積極開發中。 它的 API 和實作可以隨時發生重大變更。

了解更多關於空值安全和平台類型

支援在具有 Kotlin 和 Java 代碼的模組中呼叫 Java 的 Lombok 產生的方法

警告

Lombok 編譯器外掛程式是實驗性的。 它可能會隨時被刪除或變更。 僅將其用於評估目的。 我們將感謝你在 YouTrack 中對它的意見反應。

Kotlin 1.5.20 引入了一個實驗性的 Lombok 編譯器外掛程式。 此外掛程式可以產生並在具有 Kotlin 和 Java 代碼的模組中使用 Java 的 Lombok 宣告。 Lombok 註解僅在 Java 原始碼中有效,如果你在 Kotlin 代碼中使用它們,則會被忽略。

此外掛程式支援以下註解:

  • @Getter, @Setter
  • @NoArgsConstructor, @RequiredArgsConstructor, 和 @AllArgsConstructor
  • @Data
  • @With
  • @Value

我們將繼續研究此外掛程式。 若要了解詳細的目前狀態,請造訪 Lombok 編譯器外掛程式的 README

目前,我們沒有計畫支援 @Builder 註解。 但是,如果你在 YouTrack 中投票支援 @Builder,我們可以考慮。

了解如何設定 Lombok 編譯器外掛程式

Kotlin/Native

Kotlin/Native 1.5.20 提供了新功能和工具改進的預覽:

選擇性地將 KDoc 註解匯出到產生的 Objective-C 標頭

警告

將 KDoc 註解匯出到產生的 Objective-C 標頭的功能是實驗性的。 它可能會隨時被刪除或變更。 需要選擇加入(請參閱下面的詳細資訊),並且你應僅將其用於評估目的。 我們將感謝你在 YouTrack 中對它的意見反應。

你現在可以設定 Kotlin/Native 編譯器以將 文件註解 (KDoc) 從 Kotlin 代碼匯出到從其產生的 Objective-C 框架,使其對框架的消費者可見。

例如,以下具有 KDoc 的 Kotlin 代碼:

/**
* Prints the sum of the arguments.
* Properly handles the case when the sum doesn't fit in 32-bit integer.
*/
fun printSum(a: Int, b: Int) = println(a.toLong() + b)

產生以下 Objective-C 標頭:

/**
* Prints the sum of the arguments.
* Properly handles the case when the sum doesn't fit in 32-bit integer.
*/
+ (void)printSumA:(int32_t)a b:(int32_t)b __attribute__((swift_name("printSum(a:b:)")));

這也適用於 Swift。

若要試用此將 KDoc 註解匯出到 Objective-C 標頭的功能,請使用 -Xexport-kdoc 編譯器選項。 將以下程式碼行新增到你要從中匯出註解的 Gradle 專案的 build.gradle(.kts) 中:

kotlin {
targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget> {
compilations.get("main").kotlinOptions.freeCompilerArgs += "-Xexport-kdoc"
}
}

如果你使用此 YouTrack 問題追蹤器 與我們分享你的意見反應,我們將非常感激。

編譯器錯誤修復

Kotlin/Native 編譯器在 1.5.20 中收到了多個錯誤修復。 你可以在變更日誌中找到完整的清單。

有一個重要的錯誤修復會影響相容性:在先前的版本中,包含不正確 UTF 代理配對 的字串常數在編譯期間會遺失其值。 現在保留了這些值。 應用程式開發人員可以安全地更新到 1.5.20 – 不會發生任何中斷。 但是,使用 1.5.20 編譯的函式庫與先前的編譯器版本不相容。 有關詳細資訊,請參閱 此 YouTrack 問題

改進了 Array.copyInto() 在一個陣列內的效能

我們改進了 Array.copyInto() 在其來源和目的地是同一陣列時的工作方式。 現在,由於此使用案例的記憶體管理最佳化,此類操作的完成速度提高了 20 倍(取決於複製的物件數量)。

Kotlin/JS

使用 1.5.20,我們發布了一個指南,該指南將幫助你將專案遷移到 Kotlin/JS 的新 基於 IR 的後端

JS IR 後端的遷移指南

新的 JS IR 後端的遷移指南 識別了你在遷移期間可能遇到的問題,並提供了這些問題的解決方案。 如果你發現指南中未涵蓋的任何問題,請將其報告給我們的 問題追蹤器

Gradle

Kotlin 1.5.20 引入了以下可以改善 Gradle 體驗的功能:

kapt 中註解處理器的類別載入器的快取

警告

kapt 中註解處理器類別載入器的快取是實驗性的。 它可能會隨時被刪除或變更。 僅將其用於評估目的。 我們將感謝你在 YouTrack 中對它的意見反應。

現在有一個新的實驗性功能可以快取 kapt 中註解處理器的類別載入器。 此功能可以提高連續 Gradle 執行的 kapt 速度。

若要啟用此功能,請在你的 gradle.properties 檔案中使用以下屬性:

# positive value will enable caching
# use the same value as the number of modules that use kapt
kapt.classloaders.cache.size=5

# disable for caching to work
kapt.include.compile.classpath=false

了解更多關於 kapt

kotlin.parallel.tasks.in.project 建置屬性的棄用

在此版本中,Kotlin 並行編譯由 Gradle 並行執行標誌 --parallel 控制。 使用此標誌,Gradle 並行執行任務,從而提高了編譯任務的速度並更有效地利用了資源。

你不再需要使用 kotlin.parallel.tasks.in.project 屬性。 此屬性已被棄用,將在下一個主要版本中刪除。

標準函式庫

Kotlin 1.5.20 變更了多個用於處理字元的函數的平台特定實作,因此實現了跨平台的統一:

支援 Kotlin/Native 和 Kotlin/JS 中 Char.digitToInt() 的所有 Unicode 數字

Char.digitToInt() 傳回字元表示的十進制數字的數值。 在 1.5.20 之前,該函數僅支援 Kotlin/JVM 的所有 Unicode 數字字元:Native 和 JS 平台上的實作僅支援 ASCII 數字。

從現在開始,使用 Kotlin/Native 和 Kotlin/JS,你可以在任何 Unicode 數字字元上呼叫 Char.digitToInt() 並取得其數值表示。

fun main() {

val ten = '\u0661'.digitToInt() + '\u0039'.digitToInt() // ARABIC-INDIC DIGIT ONE + DIGIT NINE
println(ten)

}

統一了跨平台的 Char.isLowerCase()/isUpperCase() 實作

函數 Char.isUpperCase()Char.isLowerCase() 根據字元的大小寫傳回布林值。 對於 Kotlin/JVM,該實作會檢查 General_CategoryOther_Uppercase/Other_Lowercase Unicode 屬性

在 1.5.20 之前,其他平台的實作以不同的方式工作,並且僅考慮一般類別。 在 1.5.20 中,實作在跨平台之間統一,並使用這兩個屬性來判斷字元大小寫:

fun main() {

val latinCapitalA = 'A' // has "Lu" general category
val circledLatinCapitalA = 'Ⓐ' // has "Other_Uppercase" property
println(latinCapitalA.isUpperCase() && circledLatinCapitalA.isUpperCase())

}