Kotlin 2.4.20-Beta1 的新功能
本文件並未涵蓋早期體驗預覽 (EAP) 發佈版的所有功能,但重點介紹了一些重大改進。
請參閱 GitHub 變更日誌 中的完整變更列表。
Kotlin 2.4.20-Beta1 版本已發佈!以下是此 EAP 版本的一些詳細資訊:
- 標準函式庫:支援協同程式堆疊追蹤恢復
- Kotlin/Native:
klib構件預設啟用增量編譯 - Kotlin/Wasm:頂層
require()呼叫的變更,以及改進的伴隨物件初始化順序 - Kotlin/JS:用於瀏覽器測試的新 DSL
- 建置工具 API:支援新目標:Kotlin/JS、Kotlin/Wasm 以及 Kotlin 元資料
有關 Kotlin 發佈週期的資訊,請參閱 Kotlin 發佈程序。
更新到 Kotlin 2.4.20-Beta1
最新版本的 Kotlin 已包含在最新版本的 IntelliJ IDEA 和 Android Studio 中。
若要更新到新的 Kotlin 版本,請確保您的 IDE 已更新至最新版本,並在建置指令碼中將 Kotlin 版本更改為 2.4.20-Beta1。
標準函式庫:支援協同程式堆疊追蹤恢復
Kotlin 2.4.20-Beta1 在標準函式庫中新增了 StackTraceRecoverable 介面。這改進了與 kotlinx.coroutines 程式庫的整合,因為它讓您可以定義如何為堆疊追蹤恢復建立新的例外執行個體,而無需增加對 kotlinx.coroutines 的相依性。
當一個協同程式拋出例外,而另一個協同程式重新拋出它時,堆疊追蹤恢復有助於偵錯。它讓您可以查看例外的源頭以及另一個協同程式在哪裡重新拋出它。
kotlinx.coroutines 程式庫透過建立一個包含額外協同程式堆疊追蹤資訊的新例外執行個體來執行堆疊追蹤恢復。對於建構函式僅接受例外訊息、原因、兩者皆有或不含參數的例外,這會自動發生。
如果例外建構函式具有額外的必要參數(例如行號或錯誤代碼),請實作 StackTraceRecoverable 介面,以定義 kotlinx.coroutines 程式庫如何建立該例外的新執行個體。
若要執行此操作,請覆寫 copyForStackTraceRecovery() 函式。此函式會回傳一個用於堆疊追蹤恢復的新例外執行個體,如果您不希望 kotlinx.coroutines 程式庫複製該例外,則回傳 null。
StackTraceRecoverable介面在所有目標上皆可用,但kotlinx.coroutines程式庫僅在 JVM 上將其用於堆疊追蹤恢復。
這些 API 處於實驗性階段,需要使用 @OptIn(ExperimentalStdlibCoroutineSupportApi::class) 註解進行選擇加入。
以下是一個自訂例外的範例,它在為堆疊追蹤恢復建立新執行個體時會保留 line 屬性:
import kotlin.coroutines.ExperimentalStdlibCoroutineSupportApi
import kotlin.coroutines.StackTraceRecoverable
@OptIn(ExperimentalStdlibCoroutineSupportApi::class)
class FileEditException
// 此實作需要一個私有建構函式
// 以便將 cause 傳遞給 IllegalStateException 建構函式
private constructor(
val line: Int,
private val detail: String,
cause: Throwable?,
) : IllegalStateException("When editing line $line: $detail", cause),
// 實作 StackTraceRecoverable 以進行堆疊追蹤恢復
StackTraceRecoverable<FileEditException> {
constructor(line: Int, detail: String) : this(line, detail, null)
// 複製行號和訊息詳細資訊
override fun copyForStackTraceRecovery(): FileEditException =
FileEditException(line, detail, this)
}
@OptIn(ExperimentalStdlibCoroutineSupportApi::class)
fun main() {
val original = FileEditException(15, "Unexpected token")
val copy = original.copyForStackTraceRecovery()
println(copy.message)
// When editing line 15: Unexpected token
println(copy.cause == original)
// true
}如需更多資訊,請參閱該功能的 KEEP。我們歡迎您在 YouTrack 中向我們提供回饋。
Kotlin/Native:預設啟用增量編譯
從 2.4.20-Beta1 開始,klib 構件的增量編譯已預設啟用。
透過增量編譯,如果專案模組產生的 klib 構件僅有一部分發生變更,則只有 klib 中受影響的部分會進一步重新編譯為二進位檔案。
此最佳化最初是在 Kotlin 1.9.20 中引入的,並已證明能大幅縮短偵錯組建的編譯時間。
請注意,在某些情況下,此最佳化可能會對全新組建(clean build)產生效能開銷。
如果您在使用此功能時遇到意外問題,可以手動將其停用。若要停用,請在您的 gradle.properties 檔案中設定以下選項:
kotlin.incremental.native=false請在我們的問題追蹤器 YouTrack 回報任何問題。如需更多關於縮短編譯時間的提示,請參閱我們的文件。
Kotlin/Wasm
Kotlin 2.4.20-Beta1 更改了 Kotlin/Wasm 處理 @JsFun 宣告中頂層 require() 呼叫的方式,並使伴隨物件的初始化順序與 JVM 行為一致。
針對 @JsFun 宣告中頂層 require() 呼叫的變更
當 @JsFun 宣告使用頂層 require() 函式時,Kotlin/Wasm 現在會報錯。
先前,編譯器會在 import-object.mjs 檔案中產生一個 require 變數,允許 @JsFun 宣告呼叫 require()。
此行為無意中洩露了編譯器的實作細節。為了支援從中遷移,Kotlin/Wasm 移除了此產生的 require 宣告,且編譯器現在會針對此類呼叫報錯。例如:
// 會報錯
@JsFun("(mod) => require(mod)")
external fun loadModule(mod: String): JsAny為了準備應對此變更,請將 @JsFun 宣告中的頂層 require() 呼叫替換為 @JsModule 註解:
@JsModule("module")
external val module: Module
external interface Module {
// 定義預期的模組成員
}對於動態模組載入,請改用 import() 運算式。新增 /* webpackIgnore: true */ 魔術註解以防止 webpack 解析該動態匯入:
@JsFun(
"""
((module) => () => module)(
await import(/* webpackIgnore: true */ "module")
)
"""
)
private external fun loadModuleDynamically(): JsAny?您也可以有條件地使用 import() 運算式。例如,您可以僅在 Node.js 中執行時載入模組:
@JsFun(
"""
((module) => () => module)(
((typeof process !== "undefined") && (process.release.name === "node"))
? await import(/* webpackIgnore: true */ "module")
: null
)
"""
)
private external fun loadNodeModule(): JsAny?如果您的專案相依於需要頂層 require() 函式的相依性,可以將其作為 globalThis 的屬性加入作為權宜之計:
@JsFun(
"""
((module) => {
globalThis.require = module.default.createRequire(import.meta.url)
return () => {}
})(await import("node:module"))
"""
)
external fun defineRequire()如果您遇到任何問題,請在我們的問題追蹤器分享您的回饋。
改進的伴隨物件初始化順序
Kotlin/Wasm 現在會在子類別伴隨物件之前初始化父類別伴隨物件,與 JVM 行為一致。先前,初始化順序可能會反過來,導致跨平台行為不一致。
此更新改進了跨平台的一致性,並減少了類別初始化行為在不同平台間的差異。它還能正確處理更深層繼承階層中的伴隨物件初始化,包括中間類別未宣告伴隨物件的情況。
Kotlin/JS:用於瀏覽器測試的新 DSL
Kotlin 2.4.20-Beta1 引入了一種新的實驗性 DSL,用於在瀏覽器環境中執行 Kotlin/JS 測試。
目前,Kotlin Gradle 外掛程式使用 Karma 作為瀏覽器啟動器,以便在不同的瀏覽器中執行 JavaScript 測試。Karma 專案已經過時 2 年了,這促使我們探索支援瀏覽器測試的替代方案。
新的 DSL 旨在取代 Karma 作為底層不同工具的管理員,其內容包括:
- Mocha 作為測試執行器。
- Webpack 作為綑綁器(在未來版本中將被 Vite 取代)。
- Playwright 作為瀏覽器驅動程式和發行管理員,支援 Chromium、Firefox 和 WebKit (Safari) 瀏覽器引擎。
若要嘗試新的測試 DSL,請在 Kotlin/JS 目標的 browser{} 區塊內新增選擇啟用的 test{} 區塊:
kotlin {
js {
browser {
@OptIn(ExperimentalJsTestDsl::class)
// 新增並設定新的 test{} 區塊
test {
// 設定所有瀏覽器通用的選項
browserDefaults {
timeout = Duration.ofSeconds(2)
headless = true
}
// 啟用 Chromium 測試執行器
chromium {
// 覆寫通用的逾時選項
timeout = Duration.ofSeconds(5)
launchArgs.add("--no-sandbox")
}
// 啟用 Firefox 測試執行器
firefox()
// 啟用 WebKit 測試執行器
webkit { }
// 啟用並設定額外的 WebKit 測試執行器
webkit("noheadless") {
// 設定自訂選項
headless = false
}
}
}
}
}新的 DSL 正在積極開發中。我們歡迎您在 YouTrack 中向我們提供回饋。
建置工具 API:支援 Kotlin/JS、Kotlin/Wasm 以及 Kotlin 元資料
在 Kotlin 2.2.0 中,建置工具 API (BTA) 已可用於 Kotlin/JVM。Kotlin 2.4.20-Beta1 邁出了 BTA 穩定化的下一步,新增了對新目標的支援:Kotlin/JS、Kotlin/Wasm 以及 Kotlin 元資料。
這使得 Kotlin Gradle 外掛程式與編譯器的互動更加一致。在某些情況下,您還可以受益於更快、更穩定的編譯。
BTA 是一個通用 API,充當建置系統與 Kotlin 編譯器生態系統之間的抽象層。它有助於在現有的建置工具中支援 Kotlin 功能以及與 Kotlin 編譯器的相容性。
我們計劃在 Kotlin Gradle 外掛程式中逐步推出對新目標的 BTA 支援:
在 Kotlin 2.4.20-Beta1 中,BTA 在 Kotlin/JS、Kotlin/Wasm 和 Kotlin 元資料中預設啟用以收集回饋。專案不需要進行額外的變更。
在 Kotlin 2.4.20-Beta2 與最終的 Kotlin 2.4.20 版本之間,新目標中的 BTA 將作為選擇加入功能提供。若要嘗試,請將相應屬性新增到您的
gradle.properties檔案中:kotlinkotlin.wasm.runViaBuildToolsApi = true kotlin.js.runViaBuildToolsApi = true kotlin.metadata.runViaBuildToolsApi = true從 Kotlin 2.5.0 開始,BTA 將再次在 Kotlin/JS、Kotlin/Wasm 和 Kotlin 元資料中預設啟用。
如果您對 BTA 提案感到好奇或想分享您的回饋,請參閱此 KEEP。
