Kotlin 1.2 的新特性

Kotlin 1.2 的新特性

目錄

多平台項目(實驗性的)

多平台項目是Kotlin 1.2中的一個新的實驗性的特性,允許你在支持Kotlin的目標平台——JVM、JavaScript以及(將來的)Native之間重用代碼。在多平台項目中,你有三種模塊:
  • 一個公共模塊包含平台無關代碼,以及無實現的依賴平台的API聲明。
  • 平台模塊包含通用模塊中的平台相關聲明在指定平台的實現,以及其他平台相關代碼。
  • 常規模塊針對指定的平台,既可以是平台模塊的依賴,也可以依賴平台模塊。
當你為指定平台編譯多平台項目時,既會生成公共代碼也會生成平台相關代碼。
多平台項目支持的一個主要特點是可以通過預期聲明與實際聲明來表達公共代碼對平台相關部分的依賴關係。一個預期聲明指定一個API(類、接口、註解、頂層聲明等)。一個實際聲明要么是該API的平台相關實現,要么是一個引用到在一個外部庫中該API的一個既有實現的別名。這是一個示例:
在公共代碼中:
在JVM 平台代碼中:
關於構建多平台項目的詳細信息與步驟,請參見其documentation

其他語言特性

註解中的數組字面值

自Kotlin 1.2起,註解的數組參數可以通過新的數組字面值語法傳入,而無需使用arrayOf函數:
該數組字面值語法僅限於註解參數。

lateinit 頂層屬性與局部變量

lateinit修飾符現在可以用於頂層屬性與局部變量了。例如,後者可用於當一個lambda表達式作為構造函數參數傳給一個對象時,引用另一個必須稍後定義的對象:
Target platform: JVM Running on kotlin v. 1.3.11

檢查lateinit 變量是否已初始化

現在可以通過屬性引用的isInitialized來檢測該lateinit var是否已初始化:
Target platform: JVM Running on kotlin v. 1.3.11

內聯函數帶有默認函數式參數

內聯函數現在允許其內聯函式數參數具有默認值:
Target platform: JVM Running on kotlin v. 1.3.11

源自顯式類型轉換的信息會用於類型推斷

Kotlin編譯器現在可將類型轉換信息用於類型推斷。如果你調用一個返回類型參數T的泛型方法並將返回值轉換為指定類型Foo,那麼編譯器現在知道對於本次調用需要綁定類型為Foo
這對於Android開發者來說尤為重要,因為編譯器現在可以正確分析Android API級別26中的泛型findViewById調用:

智能類型轉換改進

當一個變量有安全調用表達式與空檢測賦值時,其智能轉換現在也可以應用於安全調用接收者:
Target platform: JVM Running on kotlin v. 1.3.11
智能轉換現在也允許用於在lambda 表達式中局部變量,只要這些局部變量僅在lambda 表達式之前修改即可:
Target platform: JVM Running on kotlin v. 1.3.11

支持::foo 作為this::foo 的簡寫

現在寫綁定到this成員的可調用引用可以無需顯式接收者,即::foo取代 this::foo這也使在引用外部接收者的成員的lambda表達式中使用可調用引用更加方便

阻斷性變更:try 塊後可靠智能轉換

Kotlin以前將try塊中的賦值語句用於塊後的智能轉換,這可能會破壞類型安全與空安全並引發運行時故障。這個版本修復了該問題,使智能轉換更加嚴格,但可能會破壞一些依靠這種智能轉換的代碼。
如果要切換到舊版智能轉換行為,請傳入回退標誌-Xlegacy-smart-cast-after-try作為編譯器參數。該參數會在Kotlin 1.3中棄用。

棄用:數據類棄用copy

當從已具有簽名相同的copy函數的類型派生數據類時,為數據類生成的copy 實現使用超類型的默認值,這導致反直覺行為,或者導致運行時失敗,如果超類型中沒有默認參數的話。
導致copy衝突的繼承在Kotlin 1.2中已棄用並帶有警告,而在Kotlin 1.3中將會是錯誤。

棄用:枚舉條目中的嵌套類型

由於初始化邏輯的問題,已棄用在枚舉條目內部定義一個非inner class 的嵌套類。這在Kotlin 1.2中會引起警告,而在Kotlin 1.3中會成為錯誤。

棄用:vararg 單個命名參數

為了與註解中的數組字面值保持一致,向一個命名參數形式的vararg參數傳入單個項目的用法(foo(items = i))已被棄用。請使用伸展操作符連同相應的數組工廠函數:
在這種情況下有一項防止性能下降的優化可以消除冗餘的數組創建。單參數形式在Kotlin 1.2 中會產生警告,而在Kotlin 1.3中會放棄。

棄用:擴展Throwable 的泛型類的內部類

繼承自Throwable的泛型類的內部類可能會在throw-catch場景中違反類型安全性,因此已棄用,在Kotlin 1.2中會是警告,而在Kotlin 1.3中會是錯誤。

棄用:修改只讀屬性的幕後字段

通過在自定義getter中賦值field = ……來修改只讀屬性的幕後字段的用法已被棄用,在Kotlin 1.2中會是警告,而在Kotlin 1.3中會是錯誤。

標準庫

Kotlin 標準庫構件與拆分包

Kotlin標準庫現在完全兼容Java 9的模塊系統,它禁止拆分包(多個jar文件聲明的類在同一包中)。為了支持這點,我們引入了新的kotlin-stdlib-jdk7 與kotlin-stdlib-jdk8,它們取代了舊版的kotlin-stdlib-jre7kotlin-stdlib-jre8
在Kotlin看來新的構件中的聲明在相同的包名內,而在Java看來有不同的包名。因此,切換到新的構件無需修改任何源代碼。
確保與新的模塊系統兼容的另一處變更是在kotlin-reflect庫中刪除了 kotlin.reflect包中棄用的聲明。如果你正在使用它們,你需要切換到使用kotlin.reflect.full包中的聲明,自Kotlin 1.1起就支持這個包了。

windowed、chunked、zipWithNext

用於IterableSequenceCharSequence的新的擴展覆蓋了這些應用場景:緩存或批處理(chunked)、滑動窗口與計算滑動均值(windowed)以及處理成對的後續條目(zipWithNext):
Target platform: JVM Running on kotlin v. 1.3.11

fill、replaceAll、shuffle/shuffled

添加了一些用於操作列表的擴展函數:MutableListfillreplaceAllshuffle,以及只讀Listshuffled
Target platform: JVM Running on kotlin v. 1.3.11

kotlin-stdlib 中的數學運算

為滿足由來已久的需求,Kotlin 1.2添加了JVM與JS公用的用於數學運算的kotlin.mathAPI,包含以下內容:
  • 常量:PIE
  • 三角函數:cossintan及其反函數:acosasinatanatan2
  • 雙曲函數:coshsinhtanh及其反函數:acoshasinhatanh
  • 指數函數:pow(擴展函數)、sqrthypotexpexpm1
  • 對數函數:loglog2log10lnln1p
  • 取整:
    • ceilfloortruncateround(奇進偶舍)函數;
    • roundToIntroundToLong(四捨五入)擴展函數;
  • 符號與絕對值:
    • abssign函數;
    • absoluteValuesign擴展屬性;
    • withSign 擴展函數;
  • 兩個數的最值函數:maxmin
  • 二進製表示:
    • ulp 擴展屬性;
    • nextUpnextDownnextTowards擴展函數;
    • toBitstoRawBitsDouble.fromBits(這些在kotlin包中)。
這些函數同樣也有Float參數版本(但不包括常量)。

用於BigInteger 與BigDecimal 的操作符與轉換

Kotlin 1.2引入了一些使用 BigIntegerBigDecimal運算以及由其他數字類型創建它們的函數。具體如下:
  • toBigInteger用於IntLong
  • toBigDecimal用於IntLongFloatDouble以及BigInteger
  • 算術與位運算操作符函數:
    • 二元操作符 +-*/%以及中綴函數andorxorshlshr
    • 一元操作符-++--以及函數inv

浮點數到比特的轉換

添加了用於將DoubleFloat與其比特表示形式相互轉換的函數:
  • toBitstoRawBits對於Double返回Long而對於Float返回Int
  • Double.fromBitsFloat.fromBits用於有相應比特表示形式創建浮點數。

正則表達式現在可序列化

kotlin.text.Regex類現在已經是Serializable的了並且可用在可序列化的繼承結構中。

如果可用,Closeable.use 會調用Throwable.addSuppressed

當在其他異常之後關閉資源期間拋出一個異常,Closeable.use函數會調用Throwable.addSuppressed 。
要啟用這個行為,需要依賴項中有kotlin-stdlib-jdk7

JVM 後端

構造函數調用規範化

自1.0版起,Kotlin就已支持帶有復雜控制流的表達式,諸如try-catch表達式以及內聯函數。根據Java虛擬機規範這樣的代碼是有效的。不幸的是,當這樣的表達式出現在構造函數調用的參數中時,一些字節碼處理工具不能很好地處理這種代碼。
為了緩解這種字節碼處理工具用戶的這一問題,我們添加了一個命令行選項(-Xnormalize-constructor-calls=模式),告訴編譯器為這樣的構造過程生成更接近Java的字節碼。其中模式是下列之一:
  • disable(默認)——以與Kotlin 1.0 即1.1 相同的方式生成字節碼;
  • enable——為構造函數調用生成類似Java 的字節碼。這可能會改變類加載與初始化的順序;
  • preserve-class-initialization——為構造函數調用生成類似Java的字節碼,並確保類初始化順序得到保留。這可能會影響應用程序的整體性能;僅用在多個類之間共享一些複雜狀態並在類初始化時更新的場景中。
“人工”解決辦法是將具有控制流的子表達式的值存儲在變量中,而不是直接在調用參數內對其求值。這與-Xnormalize-constructor-calls=enable類似。

Java 默認方法調用

在Kotlin 1.2之前,針對JVM 1.6的接口成員覆蓋Java默認方法會產生一個關於超類型調用的警告:Super calls to Java default methods are deprecated in JVM target 1.6. Recompile with '-jvm-target 1.8'(“針對JVM 1.6的Java默認方法的超類型調用已棄用,請使用'-jvm-target 1.8 '重新編譯”)。在Kotlin 1.2中,這是一個**錯誤**,因此這樣的代碼都需要針對JVM 1.8編譯。

阻斷性變更:平台類型x.equals(null) 的一致行為

在映射到Java原生類型(Int!Boolean!Short!Long!Float!Double!Char!)的平台類型上調用x.equals(null),當xnull時錯誤地返回了true自Kotlin 1.2起,在平台類型的空值上調用x.equals(……)都會拋出NPE (但x == ...不會)。
要返回到1.2之前的行為,請將標誌-Xno-exception-on-explicit-equals-for-boxed-null傳給編譯器。

阻斷性變更:修正平台null 透過內聯擴展接收者逃逸

在平台類型的空值上調用內聯擴展函數並沒有檢測接收者是否為null, 因而允許null 逃逸到其他代碼中。Kotlin 1.2 在調用處強制執行這項檢測, 如果接收者為空就拋出異常。
要切換到舊版行為,請將回退標誌-Xno-receiver-assertions傳給編譯器。

JavaScript 後端

默認啟用TypedArrays 支持

將Kotlin原生數組(如IntArrayDoubleArray等)翻譯為JavaScript有類型數組的JS有類型數組支持之前是選擇性加入的功能,現在已默認啟用。

工具

警告作為錯誤

編譯器現在提供一個將所有警告視為錯誤的選項。可在命令行中使用-Werror,或者在Gradle中使用以下代碼片段:
參考資料,google 繁體中文機器翻譯:https://kotlinlang.org/docs/reference/whatsnew12.html

這個網誌中的熱門文章

最新入門零基礎 Java 教學【從零開始學 Java 程式設計】Java教學課程目錄 (IntelliJ IDEA 開發教學)

2023 最新入門零基礎 Kotlin教學【從零開始學 Kotlin 程式設計】Kotlin 教學課程目錄 (Android Kotlin, IntelliJ IDEA, Android Studio, Android APP 開發教學)

Android Studio 歷代版本下載點

nano 文字編輯器

2022 最新入門零基礎 Flutter教學 【Flutter 程式設計入門實戰 30 天】Flutter 教學課程目錄 (IntelliJ IDEA 開發教學)