一、概述
The Kotlin 2.1.20 release is here! Here are the main highlights:
Kotlin 2.1.20發布了,主要亮點如下:
- K2 compiler updates: updates to the new kapt and Lombok plugins
- Kotlin Multiplatform: new DSL to replace Gradle’s Application plugin
- Kotlin/Native: support for Xcode 16.3 and a new inlining optimization
- Kotlin/Wasm: default custom formatters, support for DWARF, and migration to Provider API
- Gradle support: compatibility with Gradle’s Isolated Projects and custom publication variants
- Standard library: common atomic types, improved UUID support, and new time-tracking functionality
- Compose compiler: relaxed restrictions on @Composable functions and other updates
- Documentation: notable improvements to the Kotlin documentation.
二、常見原子類型
在Kotlin 2.1.20中,我們在標準庫的Kotlin .concurrent.atomics包中引入了公共原子類型,為線程安全操作啟用了共享的、獨立于平臺的代碼。
通過消除跨源集復制原子相關邏輯的需要,這簡化了Kotlin Multiplatform項目的開發。
kotlin.concurrent.atomics包及其屬性是實驗性的。要選擇加入,使用@OptIn(ExperimentalAtomicApi::class)注釋或編譯器選項-opt-in=kotlin.ExperimentalAtomicApi。
下面是一個示例,展示了如何使用AtomicInt在多個線程中安全地計數已處理的項:
示例執行效果圖
@OptIn(ExperimentalAtomicApi::class)
suspend fun testExperimentalAtomicApi() {var processedItems = AtomicInt(0)val totalItems = 100val items = List(totalItems) { "item$it" }// Splits the items into chunks for processing by multiple coroutinesval chunkSize = 20val itemChunks = items.chunked(chunkSize)// chunked函數 將List分割為指定大小的子數組(List),// itemChunks 5個數組,每個數組里有20個元素coroutineScope {for (chunk in itemChunks) {launch {for (item in chunk) {println("Processing $item in thread ${Thread.currentThread()}")processedItems.incrementAndFetch()}}}}println("processedItems = $processedItems")
}suspend fun main() {testExperimentalAtomicApi()
}
為了在Kotlin的原子類型和Java的Java .util.concurrent.atomic原子類型之間實現無縫的互操作性,API提供了. asjavaatomic()和. askotlinatomic()擴展函數。
在JVM上,Kotlin原子和Java原子在運行時是相同的類型,因此您可以在沒有任何開銷的情況下將Java原子轉換為Kotlin原子,反之亦然。
下面的例子展示了Kotlin和Java原子類型是如何協同工作的:
執行示例效果圖
@OptIn(ExperimentalAtomicApi::class)
fun testExperimentalAtomicApi11(){// Converts Kotlin AtomicInt to Java's AtomicIntegerval kotlinAtomic = AtomicInt(24)val javaAtomic: AtomicInteger = kotlinAtomic.asJavaAtomic()println("轉換 Java atomic 原始 value: ${javaAtomic.get()}")// 轉換 Java atomic 原始 value: 24javaAtomic.incrementAndGet()println("轉換 Java atomic 后 自增1次 value: ${javaAtomic.get()}")// 轉換 Java atomic 后 自增1次 value: 25// Converts Java's AtomicInteger back to Kotlin's AtomicIntval kotlinAgain: AtomicInt = javaAtomic.asKotlinAtomic()println("轉換 Kotlin atomic 原始 value: ${kotlinAgain.load()}")//轉換 Kotlin atomic 原始 value: 25kotlinAgain.incrementAndFetch()println("轉換 Kotlin atomic 后 自增1次 value: ${kotlinAgain.load()}")// 轉換 Kotlin atomic 后 自增1次 value: 26}suspend fun main() {testExperimentalAtomicApi11()
}
三、UUID解析、格式和可比性的變化
JetBrains團隊繼續在2.0.20中改進對標準庫中引入的uuid的支持。
以前,parse()函數只接受十六進制和破折號格式的uuid。在Kotlin 2.1.20中,可以對十六進制-破折號和普通十六進制(不帶破折號)格式使用parse()。
在這個版本中,我們還引入了一些特定于十六進制和破折號格式操作的函數:
- parseHexDash()從十六進制和破折號格式解析uid。
- toHexDashString()將Uuid轉換為十六進制和破折號格式的String(鏡像toString()的功能)。
這些函數的工作方式類似于前面介紹的十六進制格式的parseHex()和toHexString()。解析和格式化功能的顯式命名應該會提高代碼的清晰度和您使用uid的總體體驗。
Kotlin中的uid現在是可比的。從Kotlin 2.1.20開始,您可以直接比較和排序Uuid類型的值。這允許使用<和>操作符和標準庫擴展,這些擴展專門用于Comparable類型或它們的集合(例如sorted()),并且它還允許將uuid傳遞給需要Comparable接口的任何函數或api。
請記住,標準庫中的UUID支持仍然是實驗性的。要選擇加入,使用@OptIn(ExperimentalUuidApi::class)注釋或編譯器選項-opt-in=kotlin.uuid.ExperimentalUuidApi::
執行示例效果圖
@OptIn(ExperimentalUuidApi::class)
fun testExperimentalUuidApi(){// parse() accepts a UUID in a plain hexadecimal formatval uuid = Uuid.parse("550e8400e29b41d4a716446655440000")// Converts it to the hex-and-dash formatval hexDashFormat = uuid.toHexDashString()// Outputs the UUID in the hex-and-dash formatprintln(hexDashFormat)// 550e8400-e29b-41d4-a716-446655440000// Outputs UUIDs in ascending orderprintln(listOf(uuid,Uuid.parse("780e8400e29b41d4a716446655440005"),Uuid.parse("5ab88400e29b41d4a716446655440076")).sorted())// [550e8400-e29b-41d4-a716-446655440000, 5ab88400-e29b-41d4-a716-446655440076, 780e8400-e29b-41d4-a716-446655440005]
}fun main() {testExperimentalUuidApi()
}
四、新的時間跟蹤功能
從Kotlin 2.1.20開始,標準庫提供了表示某個時刻的能力。此功能以前僅在Kotlin官方庫kotlinx-datetime中可用。
kotlinx.datetime.Clock接口以kotlin.time.Clock的形式引入標準庫,kotlinx.datetime.Instant類以kotlin.time.Instant的形式引入標準庫。這些概念很自然地與標準庫中的時間包保持一致,因為與kotlinx-datetime中保留的更復雜的日歷和時區功能相比,它們只關注時間中的時刻。
當您需要精確的時間跟蹤而不考慮時區或日期時,Instant和Clock是有用的。例如,您可以使用它們來記錄帶有時間戳的事件,度量兩個時間點之間的持續時間,并獲得系統進程的當前時刻。
為了提供與其他語言的互操作性,可以使用額外的轉換器功能:
- tokotlininstant()將時間值轉換為kotlin.time.Instant實例。
- tojavainstant()將kotlin.time.Instant值轉換為java.time.Instant值。
- Instant.toJSDate()將kotlin.time.Instant值轉換為JSDate類的一個實例。這種轉換并不精確;JS使用毫秒級的精度來表示日期,而Kotlin允許納秒級的分辨率。
標準庫的新時間特性仍處于試驗階段。要選擇加入,請使用@OptIn(ExperimentalTime::class)注釋:
執行示例效果圖
@OptIn(ExperimentalTime::class)
fun testTimeClock() {// Get the current moment in timeval currentInstant = Clock.System.now()println("Current time: $currentInstant")// Find the difference between two moments in timeval pastInstant = Instant.parse("2023-01-01T00:00:00Z")val duration = currentInstant - pastInstantprintln("Time elapsed since 2023-01-01: $duration")
}
fun main() {testTimeClock()
}