Kotlin 1.3.70正式釋出

kotliner發表於2020-03-10

今天我們很高興地向你介紹目前Kotlin最新的版本1.3.70。

kotlin_1370

該增量版本不會有新的功能。這是因為我們在盡力去改善現有功能,解決問題,和新增可供嘗試的實驗性功能。下面介紹Kotlin 1.3.70的重點:

  • 在Kotlin標準庫集合中的新函式和類。
  • 針對IntelliJ Kotlin外掛的各種改進::改進了* .gradle.kts的支援,測試,除錯,補全等。
  • 現在Kotlin/JVM編譯器會對Java 8以及更高版本的位元組碼生成型別註解。
  • Bundle優化,npm依賴項宣告以及期待已久的新Kotlin/JS文件。
  • 編譯和除錯速度更快的Kotlin/Native
  • 改進了IDE和命令列工具中對指令碼的支援。

你可以在更新日誌檢視完整的變動列表。一如既往,我們非常感謝其他貢獻者

更多的細節請聽我娓娓道來。

標準庫的變化

請注意,所有新函式都以實驗狀態新增到了標準庫中。

基礎庫中StringBuilder的擴充套件

雖然StringBuilder已包含在標準庫common的kotlin.text包。但卻缺失了許多重要屬性,也僅能在JVM上使用。而現在,JVMStringBuilder的所有功能都已新增到了平臺相關的通用Expect類。這意味著你可以從通用程式碼中使用StringBuilder所有屬性。

Working with KClass

現在JVM上KClass的部分基礎屬性不再需要依賴kotlin-reflect了:

在之前,你需要在執行時提供Kotlin reflection實現以使其工作。而現在,你可以不需要任何依賴就能使用這些簡單屬性。

重新命名實驗註解(@Experimental和@UseExperimental)

如你所知,Kotlin內建能使用實驗特性的機制。包括標準庫中的註解,它們本身就是實驗性的或使用其他實驗性宣告標記的。在以前的版本,這些註解是@UseExperimental@Experimental

我們決定擴大此機制的範圍,因為使用實驗性的API還需要同意其他的要求。例如,API可以是內部的,也可以有一些限制。我們對註解的重新命名正是反映這一點:名稱@OptIn@RequiresOptIn分別代替了@UseExperimental@Experimental。編譯器引數-Xuse-experimental已重新命名為-Xopt-in。至於-Xexperimental,它的使用頻率低且會增加複雜性,因此我們將它刪除了。雖然 1.3.70仍支援舊的宣告@Experimental@UseExperimental,但在1.4中它們將被刪除。

重新命名實驗性的時間測量API

我們也重新命名了持續時間和時間測量APIClockClockMark已重新命名為TimeSourceTimeMark。而以前的名稱現在作為不推薦使用的型別別名保留了下來。

雙端佇列實現:ArrayDeque

我們很高興地將雙端佇列的實現kotlin.collections.ArrayDeque類新增到了Kotlin標準庫中!這是社群一直夢寐以求的。即便可以使用Java標準庫中的java.util.ArrayDeque類,但對於Kotlin/JS,Kotlin/Native以及通用程式碼,都沒有合適的實現。現在,儘管還處於實驗狀態,也至少是可用的實現了。

雙端佇列允許你以均攤時間向佇列的開頭和結尾新增/刪除元素:

當你的程式碼中需要佇列或堆疊時,預設情況下可以使用雙端佇列。

Kotlin.collections.ArrayDeque底層實現是一個可變長的陣列:它將內容儲存在迴圈緩衝區——一個陣列,並僅在陣列存滿時才調整其大小。

從概念上講,ArrayDeque的實現與java.util.ArrayDeque的實現非常相似。但請注意,這實際上是不同的實現,且當你在Kotlin/JVM上使用這個類時,將使用新的實現。這與其他集合的工作方式不同:建立ArrayList並在JVM進行編譯時,其背後會使用java.util.ArrayList類。與Java的ArrayDeque僅實現Collection介面不一樣的是,Kotlin的ArrayDeque實現了MutableList。這意味著你可以通過索引訪問所有元素,而這是Java的ArrayDeque無法實現的。

我們現在以實驗狀態釋出ArrayDeque類,並期待你的反饋!

集合Builder

另一個重要的新功能是集合的builder函式:buildListbuildSetbuildMap。你可以使用這樣的builder函式在建立階段方便地操作可變集合,並最終得到一個只讀的集合:

這些builder函式的實現與buildString類似。 buildList允許傳入帶有接收者的lambda作為引數。 Lambda中的隱式“ this”接收器的型別為MutableList,而buildList返回一個只讀的List作為結果。

在操作較為複雜(例如需要條件,修改多個初始集合或合併結果等)時,使用builder函式通常更具可讀性和更有效(原文為more effective in terms of performance)。請注意,這些功能目前還處於實驗狀態。

reduceOrNull()和randomOrNull()

你知道Kotlin中的約定:通常會有這樣一對函式,其中第一個函式在無法執行操作時引發異常,第二個函式返回null,例如string.toInt()string.toIntOrNull()。現在,我們按照相同的約定新增了新的randomOrNull()reduceOrNull()函式:

如果你使用random()reduce(),當集合為空時會丟擲一個異常。

scan()函式

我們新增了一組用於處理列表和序列的新函式。它們代表“掃描”的概念;類似的功能已經存在於各型別的語言當中。

scan()fold()密切相關。 scan()fold()都將給定的二進位制運算應用於值序列,但是不同之處在於scan()返回包含中間結果的序列,而fold()僅返回最終的結果。

scan也像fold一樣也需要初始值進行累加:

img

如果結果型別與元素型別相同,並且可以將第一個元素用作初始值,則可以使用reduce()scanReduce()函式:

img

請注意,在序列上使用scan()scanReduce()時,將返回一個結果序列,這些序列本質上是惰性的。這意味著只有你從結果序列中查詢資料,特別是呼叫終止操作(返回另一個序列以外的其他值),例如toList()max()時,掃描過程才會開始。在列表上使用scan()scanReduce()時,將會返回一個列表作為結果。

閱讀KEEP以瞭解更多細節。

IntelliJ IDEA的支援

該版本包括IntelliJ IDEA中對Kotlin支援的一些改進。讓我們來看看最值得關注的地方。

對*.gradle.kts的支援

在1.3.70中,我們致力於改進IntelliJ IDEA對Gradle Kotlin DSL指令碼(* .gradle.kts檔案)的支援。最新版本的Kotlin外掛在語法高亮,程式碼補全,程式碼搜尋以及其他使用Kotlin構建指令碼的方面,效能表現非常優秀。博文對這項改進有更進一步的討論。 要享受到所有變化和改進,請確保使用IntelliJ IDEA 2019.2或更高的版本,同時使用Gradle 6.0或更高的版本。

程式碼補全

在1.3.70中,我們對IntelliJ IDEA中的Kotlin程式碼補全進行了顯著的改進。現在,補全建議包含物件中宣告的函式,擴充套件函式,以及object層級重寫的函式,甚至是巢狀物件中宣告的函式。

object-extension-completion

我們還改進了針對補全列表排序的機器學習模型,現在,最相關的選項將會顯示在頂部。

新的配色方案

為了使你可以根據自己的喜好更改編輯器中Kotlin程式碼的外觀,我們新增了新的可自定義的配色方案。特別現在你可以為suspend函式呼叫和屬性宣告設定自己的配色方案了。

suspend-color-scheme

除錯的改進

在之前的版本中,Kotlin/Native偵錯程式曾經有一個單獨的斷點型別,這使部分使用者難以選擇,例如“我應該在這裡使用哪種斷點型別?”。而現在只有一個斷點型別Kotlin Line Breakpoint,用於JVM和Native。

Kotlin/JS和Kotlin/Native測試

與Kotlin/JVM測試一樣,現在可以在IntelliJ IDEA中直接顯示Kotlin/JS和Kotlin/Native的測試結果。另外,我們已經修復了Kotlin/JS的測試過濾功能,因此你可以執行單獨的測試,並且最後還可以通過點選Play按鈕直接啟動面向iOS模擬器的Kotlin/Native測試。

img

此外,在IntelliJ IDEA Ultimate中,你可以通過單擊測試宣告附近的圖示來啟動Kotlin/JS除錯。

img

另外,你可以通過在Gradle工具視窗中手動選擇nodeRunnodeTestbrowserTest任務來開始除錯。對於browserRun,可以在開發伺服器啟動後通過Attach to Node.js/Chrome 執行配置來連線到偵錯程式。

其他應該關心的提醒

IntelliJ IDEA中對Kotlin支援還進行了其他改進。這裡有部分值得一提的:

  • 改進了檔案分析和複製貼上操作的效能。
  • 新的對無意義的一元運算子的檢查。它們可能會在將長表示式拆分成多行時出現:
  • 大量格式化方面的改進,包括鏈式呼叫,換行符,空格和註解的格式化。

Kotlin/JVM

Kotlin現在可以在JVM位元組碼(版本1.8以上)中生成型別註解,以便它們在執行時可用。社群對該特性的要求已經有一段時間了,因為它讓使用某些現有Java庫更加容易,並且為那些編寫新庫的人提供了更多功能。

在以下示例中,String型別所標記的@Foo註解將輸出到位元組碼中,其提供給庫程式碼去使用:

要在位元組碼中輸出型別註解,請按照下列步驟操作:

  • 確保宣告的註解有合適的物件範圍(Java的ElementType.TYPE_USE或Kotlin的AnnotationTarget.TYPE)和可見性(AnnotationRetention.RUNTIME)。
  • 使用此註解(以上示例中的Class A)將註解類宣告和程式碼編譯版本為1.8以上的JVM位元組碼。你可以通過設定-jvm-target=1.8編譯器配置來實現。
  • 使用帶有-Xemit-jvm-type-annotations編譯器配置的註解來編譯程式碼。

請注意,由於標準庫的型別註解是使用目標版本1.6進本編譯的,因此暫時不會輸出到位元組碼中。

到目前為止,僅支援基本的使用場景:

  • 方法引數,方法返回型別和屬性型別的型別註解;
  • 型別引數的不變投影,例如Smth<@Ann Foo>Array<@Ann Foo>

未來,我們計劃支援為協變和逆變型別投影,以及內部型別的註解(例如Smth<@Ann Outer.Inner>)生成型別註解。我們認為,當前已支援的場景,應該已涵蓋了大多數實際使用情況,但是如果你需要更復雜場景的型別註解,請告訴我們。

Kotlin/JS

在Kotlin 1.3.70,JavaScript目標平臺在bundle的大小方面進行了一些重大的優化,並在處理依賴,資源和測試的方式上增加了一些提升體驗的改動。我們也很高興地宣佈針對該目標平臺的文件進行了全面的修訂。

Bundle優化

從Kotlin 1.3.70開始,現在可以通過org.jetbrains.kotlin.js Gradle外掛輕鬆獲得DCE(消除無效程式碼),而無需手動去新增。它會接收一組新任務,可用於控制JS專案的優化和執行。

在開發過程中,使用browserDevelopmentRun會以不執行優化的方式啟動應用程式及捆綁的開發伺服器。使用browserDevelopmentWebpack可以在build/distributions資料夾中生成應用程式的非優化bundle包。如果選擇不執行任何優化,則構建時間將更快,但是編譯後的程式檔案體積會更大。

而在生產環境,請使用browserProductionRun對應用程式的進行優化,並使用browserProductionWebpack生成適合在生產環境中部署的bundle。生產版本的編譯時間要更長一點,但對比開發版本會有顯著的優化:

專案開發版本 (GZIP)生產版本 (GZIP)
“Hello, World”963 KiB14 KiB
Kotlin/React Example (“CodeQuiz”)4.1 MiB345 KiB

儘管之前的Gradle任務browserRu(現在是browserDevelopmentRun的別名)和browserWebpack(現在是browserProductionWebpack的別名)仍然可用,但是你應該在構建指令碼中使用它們的新”身份”來代替。

這些Gradle任務可執行於使用了多平臺kotlin.jsGradle外掛的專案。對於kotlin.js,你還可以使用短的任務別名去執行browserDevelopmentRun和針對browserProductionWebpack進行構建

如果你想了解Kotlin/JS中消除無效程式碼,和如何以細粒度方式進行配置的更多資訊,請查閱文件

資源自動複製

現在,在分發資料夾(如browserProductionWebpack)中建立bundle的構建任務,現在也會從resources資料夾中複製所有資源,因此不再需要手動去複製圖片,樣式表等等來獲取可部署的元件。

對npm依賴宣告的平滑支援

使用Kotlin/JS Gradle外掛時,現在可以在頂級依賴塊中宣告npm依賴,而不必手動新增主要源集。這意味著以下程式碼段現在是合法的:

對Gradle測試的實驗性除錯

現在對面向瀏覽器的Kotlin/JS測試,可以直接在IntelliJ IDEA中進行除錯了。要除錯失敗(原文為failing)的測試,請在IDE中設定一個斷點,然後以除錯模式啟動Gradle任務check,或通過gutter圖示來對整組測試進行除錯。 Gradle將執行平臺的測試任務,偵錯程式將停止在綜合斷點處。 同樣一旦Gradle在控制檯中顯示browserTest任務,斷點會立即觸發:

此時,切換到偵錯程式中的browserTest會話,然後選擇標籤為“ Debugger”的選項卡。單擊“Resume Program”按鈕繼續執行測試:

js-debug

目前這個流程需要使IntelliJ IDEA的偵錯程式與JS引擎保持同步。我們知道,啟動除錯會話的步驟比較繁瑣,因此請留意之後的版本,以獲取更加流暢的除錯體驗!

我們還計劃在解決一些遺留問題後,為除錯針對Node.js的Kotlin程式碼提供相同的體驗。

文件的改進

使用Kotlin 1.3.70,我們已經對面向JavaScript的文件和教程進行了期待已久的更改,希望這讓入門Kotlin/JS更加輕鬆。我們更新了文件並刪除了過時的資料。我們還在網站上新增了一系列新的簡短教程,概述了使用Kotlin/JS時可能會遇到的典型案例。它們可以輔助你開始使用Kotlin/JS Gradle外掛,並且涵蓋了構建面向JavaScript的應用程式時的案例。動手課程“使用React和Kotlin/JS構建Web應用程式”也已更新,現在會指導你如何為Gradle啟用Kotlin/JS外掛。

我們希望這些更改能讓你更輕鬆地入門和使用Kotlin/JS,特別是如果你想嘗試進行前端開發時。我們正盡力完善文件和參考資料,以幫助你學習Kotlin/JS。因此,如果你仍然覺得文件或操作方法有所欠缺,請在評論中告知我們。

Kotlin/Native

效能改進

在1.3.70中,我們準備展示在貫穿Kotlin/Native開發流程的效能優化方面所取得的初步成果。編譯效能是Kotlin/Native開發中已知的劣勢之一,因此我們有兩個新功能可以減少編譯時間:

  • 現在,Kotlin/Native編譯器直接從Gradle守護程式執行,因此啟動新程式以及每次編譯時載入編譯器都不再有時間開銷了。
  • 在除錯模式下,編譯器將快取專案依賴。現在,第一次編譯所花費的時間會更長,但是後續編譯速度將更快。請注意,目前這僅適用於iOS模擬器(iosX64)和macOS(macosX64)。同志仍需努力。
  • 我們也沒有忘記改善執行時和除錯的效能。在1.3.70中,我們減少了部分物件的分配時間:現在更多的物件會在棧上分配(比在堆上分配更快),並且部分單例物件會在編譯時便建立了。除錯過程也變得更快。

單個應用程式支援多個Kotlin框架

之前存在一個已知問題,即應用程式不能使用多個動態Kotlin/Native框架,因為來自不同的執行時例項定義的Obj-C類存在衝突。我們已經在1.3.70中修復了此問題,因此現在一個應用程式可以使用多個Kotlin/Native框架了。所有常見的依賴項都存在於框架中的不同Swift模組(以及不同的Obj-C字首)下。

支援vector型別

從1.3.70開始,Kotlin/Native支援SIMD型別。這為Kotlin/Native提供了更多第三方API,例如流行的Apple框架AccelerateSpriteKit

指令碼

1.3.70版提供了一組改進,在IntelliJ IDEA和Kotlin命令列工具中使用Kotlin指令碼將有更好的體驗。 另外,為了幫助你熟悉Kotlin指令碼,我們準備了一個示例專案。它包含標準指令碼(\* .main.kts)示例,以及指令碼API用法和自定義指令碼定義示例。請嘗試一下,並在我們的問題跟蹤器中反饋。

編譯器和IDE對kotlin-main-kts的支援

在Kotlin 1.3中,我們引入了kotlin-main-kts元件,該元件簡化了基礎工具指令碼的建立和使用。現在預設情況下,它是由Kotlin編譯器和IntelliJ外掛載入的,因此\* .main.kts指令碼支援開箱即用。特別現在你可以使用這類指令碼,而無需將kotlin-main-kts.jar新增到類路徑中。 在IntelliJ IDEA中,這為* .main.kts檔案(即便在源目錄之外)提供了高亮和程式碼導航,甚至可以解析動態的依賴。 我們還通過對* .main.kts指令碼進行快取來提高執行速度,同時執行速度也大幅度提高。

命令列工具

我們還擴充套件了命令列工具中對Kotlin指令碼的支援。 Kotlin命令列編譯器附帶的kotlin 執行器現在支援執行指令碼。要使用kotlin執行指令碼,只需給它傳遞指令碼的檔名:

這樣的呼叫將與使用-script配置呼叫編譯器以完全相同的方式執行指令碼。 kotlin.main.kts的識別是開箱即用的。 kotlin執行器也可以用於表示式求值。要對錶達式進行求值,請將其作為引數傳遞給–e / -expression配置項:

你將立即獲得結果。 相同的功能已新增到Kotlin命令列編譯器,但有不一樣的配置名:-Xexpression

如何更新

同樣的,你可以在play.kotl.in使用線上Kotlin

  • Gradle或Maven:指定編譯器及標準庫的版本為1.3.70。參考GradleMaven的文件。
  • IntelliJ IDEAAndroid Studio:開啟Tools | Kotlin | Configure Kotlin Plugin Updates然後點選“Check again”按鈕,以更新Kotlin外掛到1.3.70版本。
  • Eclipse:通過Marketplace安裝外掛。
  • 可以在Github釋出頁面下載命令列編譯器

如果你在新版本中遇到任何問題,歡迎在Slack(在這裡獲得邀請)的論壇上尋求幫助,或在問題跟蹤器中報告。

Let’s Kotlin!

其他貢獻者

我們要感謝Fleshgrinder在為集合新增的builder函式方面所做的工作,以及adellibovi在新增reduceOrNull()函式方面所做的工作。

同樣感謝提交的PR合併到該版本中的所有其他貢獻者:

相關文章