今天,很高興迎來最後一個里程碑預覽版Kotlin 1.4–1.4-M3。在這篇部落格中,我們將引導你瞭解該預覽版帶給Kotlin標準庫的更改。其他元件也在M3中得到更新。我們將在另一篇部落格介紹候選版本(1.4-RC),以最終敲定Kotlin 1.4。
1.4-M3中標準庫的變動如下:
- 現在JVM庫已包含
模組
修飾符了 - 函式式介面已被新增到標準庫中
- 新的集合操作覆蓋更貼切的用例
@Throws
annotation in the common library- Deprecation of some functions on floating-point arrays
你可以在更新日誌中檢視完整的變動列表。一如既往,我們非常感謝其他貢獻者。
標準庫工件已包含模組修飾符
從Java 9開始,得益於Jigsaw專案,你可以將應用程式模組化。透過jlink工具,你可以建立一個自定義Java執行時映象,該映象僅包括應用程式所需的平臺模組。之前你可以同時使用jlink
和Kotlin標準庫工件,但為此必須使用單獨帶有“模組化”分類器的工件——並且整個配置並不容易。無法在主要工件中包含模組修飾符是Android工具引起的,現在該問題已得以修復。
Kotlin 1.4將module-info.java
模組資訊新增到預設的標準庫構件中,因此它們能輕鬆地與jlink
結合使用。在Android中,請確保使用3.2以及更高版本的Android Gradle外掛,該外掛能正確處理帶有模組修飾符的jar包。
標準庫中的函式式介面
Kotlin 1.4支援Kotlin類的SAM轉換。你可以將僅有一個抽象方法的介面標記為fun interface
,便可向引數型別為此介面的方法傳遞lammbda。在標準庫中,以下介面現已宣告為fun interface
:
Comparator
ReadOnlyProperty
PropertyDelegateProvider
(在1.4-M2引入)
你可以透過以lambda作為引數的SAM建構函式來建立例項。這會讓程式碼變得更加簡潔:
集合操作
新增一個sumOf
函式,其接受一個selector函式,並返回集合所有元素上的值的總和。它與現有的sumBy
和sumByDouble
函式非常相似。關鍵區別在於新sumOf
的selector函式支援多種資料型別,從而能以同一種方式求取不同資料型別的總和。sumOf
可以給型別為Int
,Long
,Double
,UInt
,ULong
求和。在JVM上還可作用於BigInteger
和BigDecimal
。
min
和max
函式已重新命名為minOrNull
和maxOrNull
。自1.0版引入以來,空集的min
和max
會返回null
。這不符合Kotlin集合API中的命名規範:如果接收者集合為空,則沒有*OrNull
字尾的函式會引發異常。要得到null
,請使用函式的*OrNull
版本,例如firstOrNull
。 因此,我們決定逐漸改變min
和max
的行為。在1.4-M3中,我們將minOrNull
和maxOrNull
新增為min
和max
的同義詞,並開始min
和max
的棄用週期,以使用非null返回型別重新引入它們。- 我們引入了
minOf
和maxOf
函式,它們將返回selector函式所作用集合的最小值或最大值。這些函式可覆蓋map { selector }.max()!!
和maxBy { selector }!!.selector
(或min
和minBy
)的場景。
為了與現有API保持一致,我們還新增了minOfWith
和maxOfWith
,它們均以Comparator
作為引數。 所有的這四個新函式都遵循我們上面描述的非null規範:它們在空集上引發異常,並且具有* orNull版本
,在這種情況下將返回null。
flatMap
和flatMapTo
的新過載可以在返回型別與接收型別不匹配時進行轉換,即:Iterable
、Array
和Map
轉換為Sequence
Sequence
轉換為Iterable
- 新增了
flatMapIndexed
函式作為flatMap
的配對函式。你可能已知道,集合處理函式的名稱中有Indexed
意味著操作函式會帶有一個索引引數。
通用@Throws註解
儘管Kotlin沒有受檢查異常,但透過@Throws
註解 可和有此規範的語言(如Java和Swift)互操作。此前對於JVM(kotlin.jvm.Throws
)和Native(kotlin.native.Throws
),分別採取了不同名稱進行了註解。從1.4-M3開始,@ Throws
註解將直接作為kotlin包(kotlin.Throws
)公共庫的一部分,並可在公共程式碼中使用。
Swift和Objective-C中掛起函式的@Throws
在1.4-M1中,我們公佈了Objective-C/Swift互操作中異常處理方面的變動:現在,NSError
僅引發@Throws
註解(或其子類)引數的類例項的異常。在1.4-M2中,我們引入了對Swift和Objective-C中Kotlin掛起函式的基本支援。在1.4-M3,被@Throws
註解的掛起函式的行為會有微小的變化:
- 如果你使用
@Throws
註解了suspend fun
,則需要指定CancellationException :: class
作為@Throws
註解的引數。否則,編譯將報錯。 - 如果
suspend fun
上沒有@Throws
註解,在Swift呼叫時,它將隱式使用@Throws(CancellationException :: class)
。
浮點陣列中的Equality
很多人都知道這些方便的容器型別擴充套件函式—contains
,indexOf
和lastIndexOf
。不久之前,我們發現它們在浮點陣列(FloatArray
和DoubleArray
)上的行為可能存在爭議,並且看起來可能不正確。 具體來說,它們使用IEEE 754標準進行浮點運算。該標準為極端情況定義了以下判等規則:
NaN
不等於NaN
-0.0
等於0.0
這些規則可能會導致意外的結果,例如:
另外,其行為與相同函式在列表上的結果不一致,因為它們採取了total order相等:
在1.4-M3中,我們開始了FloatArray
和DoubleArray
的contains
、indexOf
和lastIndexOf
擴充套件函式的棄用週期。當你使用它們時,會看到警告以及有關這些函式代替用法的說明。 在未來的版本中,我們會將棄用級別提高到ERROR
,並從公共API中刪除這些函式。
KType轉換為Java Type
在Kotlin 1.3.40,我們向標準庫新增了一個有用的typeOf
函式。該函式返回給定泛型T
的執行時表示形式作為KType的例項。但是在許多實際場景中,你需要Java反射的[java.lang.reflect.Type
]物件(https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Type.html),而非KTypes
。儘管可以轉換,但這需要完整的kotlin-reflect
依賴。而現在我們更新了標準庫,將KType
轉換為Java Type
—一個返回Java Type
的KType.javaType
擴充套件屬性:
請注意,到目前為止,所獲取的Java型別
在某些特殊情況下(例如帶註解的型別引數或declaration-site variance)無法正常執行,因此KType.javaType
仍處於試驗階段。你可以在該issue中檢視更多未被支援場景的詳細資訊。
相容性
請注意,在某些極端情況下,Kotlin 1.4不向後相容1.3。語言委員會仔細審查了所有此類情況,並將其列入“相容性指南”(類似於這個)。當前你可以在YouTrack中找到這份列表。.
正式釋出前注意事項
請注意,向後相容性不保證包含預發行版本。其特性和API可能在後續版本中更改。當到達最終RC時,編譯器將禁止所有預發行版本產生的二進位制檔案,並且將需要你重新編譯1.4‑Mx編譯過的所有內容。
如何嘗試最新的特性
同樣的,你可以在play.kotl.in使用線上Kotlin。
在IntelliJ IDEA和Android Studio,你可以更新Kotlin外掛到1.4-M2版本。操作指南。
如果要在現有專案使用預覽版,則需要在Gradle或Maven中為預覽版本配置構建。
你可以在Github發行頁下載命令列編譯器。
你可以使用隨版本發行的庫的以下版本:
- kotlinx.atomicfu版本:0.14.3-1.4-M3
- kotlinx.coroutines版本:1.3.7-1.4-M3
- kotlinx.serialization版本:0.20.0-1.4-M3
- ktor版本:1.3.2-1.4-M3
在這裡檢視有關發行版的更多細節和相容庫列表。
分享你的反饋
如果你發現錯誤並向我們的問題跟蹤器進行報告,我們表示非常感謝。我們嘗試在最終發行版前解決所有重要問題,這意味著無需等到下一個Kotlin發行版你的問題便能得到解決。
如果你有任何疑問並想參與討論,歡迎加入Kotlin Slack (在這裡獲得邀請)的#eap頻道。在該頻道中,你還可以獲取有關新預覽版的通知。
Let’s Kotlin!
其他貢獻者
同樣感謝提交的PR合併到該版本中的所有其他貢獻者:
- Toshiaki Kameyama
- Steven Schäfer
- Jinseong Jeon
- pyos
- Mark Punzalan
- rapturemain
- Vitaly Tihonov
- Mads Ager
- Subroh Nishikori
- Juan Chen
- gcx11
- Robert Bares
- Henrik Tunedal
- Nick
- Dmitry Borodin
- Efeturi Money
- Kevin Most
- Anastasiya Krasnoryadtseva
- Kristoffer Andersen
- Martin Petrov
- Matthew Gharrity
- Mike Samuel
- Mikhail Likholetov
- Segun Famisa
- Sinan Kozak
- Vadim Semenov
- Valeriy Vyrva
- Victor Turansky
- Yuku Kotani