今天我們很高興地向你介紹目前Kotlin最新的版本1.3.70。
該增量版本不會有新的功能。這是因為我們在盡力去改善現有功能,解決問題,和新增可供嘗試的實驗性功能。下面介紹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
我們也重新命名了持續時間和時間測量API。Clock
和ClockMark
已重新命名為TimeSource
和TimeMark
。而以前的名稱現在作為不推薦使用的型別別名保留了下來。
雙端佇列實現: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函式:buildList
,buildSet
和buildMap
。你可以使用這樣的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
一樣也需要初始值進行累加:
如果結果型別與元素型別相同,並且可以將第一個元素用作初始值,則可以使用reduce()
和scanReduce()
函式:
請注意,在序列上使用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層級重寫的函式,甚至是巢狀物件中宣告的函式。
我們還改進了針對補全列表排序的機器學習模型,現在,最相關的選項將會顯示在頂部。
新的配色方案
為了使你可以根據自己的喜好更改編輯器中Kotlin程式碼的外觀,我們新增了新的可自定義的配色方案。特別現在你可以為suspend函式呼叫和屬性宣告設定自己的配色方案了。
除錯的改進
在之前的版本中,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測試。
此外,在IntelliJ IDEA Ultimate中,你可以通過單擊測試宣告附近的圖示來啟動Kotlin/JS除錯。
另外,你可以通過在Gradle工具視窗中手動選擇nodeRun
,nodeTest
或browserTest
任務來開始除錯。對於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 KiB | 14 KiB |
Kotlin/React Example (“CodeQuiz”) | 4.1 MiB | 345 KiB |
儘管之前的Gradle任務browserRu
(現在是browserDevelopmentRun
的別名)和browserWebpack
(現在是browserProductionWebpack
的別名)仍然可用,但是你應該在構建指令碼中使用它們的新”身份”來代替。
這些Gradle任務可執行於使用了多平臺
或kotlin.js
Gradle外掛的專案。對於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”按鈕繼續執行測試:
目前這個流程需要使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框架Accelerate和SpriteKit。
指令碼
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
。參考Gradle和Maven的文件。 - IntelliJ IDEA和Android 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合併到該版本中的所有其他貢獻者:
- pyos
- Steven Schäfer
- Toshiaki Kameyama
- Mark Punzalan
- Mads Ager
- Kristoffer Andersen
- Ivan Gavrilovic
- Jiaxiang Chen
- Kevin Bierhoff
- Alfredo Delli Bovi
- Tillmann Berg
- Victor Turansky
- Alexander Shustanov
- Kerooker
- Juan Chen
- Jordan Demeulenaere
- Jim Sproc
- Burak Eregar
- Dmiitrii Jarosh
- Dat Trieu
- Dmitry Borodin
- Efeturi Money
- Miguel Serra
- Fleshgrinder
- Jens Klingenberg
- Louis CAD