時光飛逝,今天我們想向你展示Kotlin 1.4的部分強大的預覽特性。在Kotlin 1.4正式釋出之前,請了解並嘗試Kotlin 1.4-M2。
我們很感謝試用了Kotlin 1.4首個預覽版並反饋以幫助Kotlin變得更完善的人!
也非常感謝嘗試了在上一篇博文所提到的*Kotlin 1.4-M2’s標準庫的改動的人。
在這篇博文中,我們將重點介紹1.4-M2中可用的新特性和關鍵改進:
- 得益於多平臺專案的分層架構,現在支援在多個目標中共享程式碼。
- 一個新的更靈活的Kotlin專案建立嚮導,更便於建立和配置不同型別的專案。
- 一個新的有助於庫作者的編譯器模式,其名稱為API模式,有助於建立統一且描述清晰的API。
- 支援在Kotlin/Native呼叫Swift和Objective-C的掛起函式。
- 完善了Kotlin/JS的Gradle DSL,支援CSS開箱即用及常見的註解匯出。
你可以在更新日誌中找到完整的變更列表。我們同樣非常感謝其他貢獻者。
多目標分層專案架構中共享程式碼
隨著專案分層架構的支援,你可以在多平臺專案的多個目標中共享程式碼。
在此之前,多平臺專案中的程式碼要麼被放入到平臺的指定源集中(僅限於一個目標,並且不能被任何其他平臺複用),要麼放入到公共源集中,例如commonMain
或commonTest
,在專案中的所有平臺之間共享。在公共源集中,你只能呼叫被expect
宣告的平臺獨立實現的actual
API。
雖然這讓在所有目標之間共享程式碼變得容易,但是在目標之間的共享卻並不容易,尤其複用通用邏輯和第三方API的相似目標。
例如,在針對iOS的典型多平臺專案中,有兩個與iOS相關的目標:一個針對iOS ARM64裝置,另一個針對x64模擬器。它們具有獨立的平臺指定的源集,但是在實踐中,幾乎不需要為裝置和模擬器使用不同的程式碼,並且它們的依賴非常相似。因此可以在它們之間共享iOS平臺特定的程式碼。
顯然,在此設定中,希望能有兩個iOS目標的共享源集,並且Kotlin/Native程式碼仍可以直接呼叫iOS裝置和模擬器共通的任何API。
現在你可以在分層專案架構來實現這一點,它會根據呼叫方的目標來推斷和調整每個源集中可用的API和語言功能。
如何使用
Install the 1.4 M2 Kotlin plugin with the hierarchical project support right now!
在你的專案gradle.properties
檔案中加入以下配置項:
請注意,從Kotlin 1.4-M2開始,層次架構以及所有多平臺專案都需要Gradle 6.0及更高版本。
你可以透過應用於典型場景的多目標快捷方式建立層次架構,也可以透過連線源集來手動建立層次架構。
例如,使用ios()
快捷方式建立兩個iOS目標以及上述所展示的共享源集:
至於其他目標的組合,透過將源集與dependsOn
連線來手動建立層次結構。
你可以為以下目標組合設定共享源集:
- JVM + JS + Native
- JVM + Native
- JS + Native
- JVM + JS
- Native
當前,我們不支援為以下目標組合共享源集:
- Several JVM targets
- JVM + Android targets
- Several JS targets
請隨時透過傳送電子郵件至feedback@kotlinlang.org與我們分享你的目標組合。這將有助於我們優先考慮更常用的組合。
庫中的共享程式碼
歸功於分層專案架構,庫還可以為目標子集提供通用API。
庫被釋出時,其共享源集的API連同相關專案結構的資訊將被嵌入到庫工件中。使用該庫時,專案的共享源集將能精確獲取到各個源集可用於目標的庫API。
例如,請檢出並瞭解kotlinx.coroutines儲存庫的native-mt分支下的源集層次結構:
併發源集宣告瞭函式runBlocking
並針對JVM和Native目標進行編譯。你可以在面向JVM及Native的目標中依賴並呼叫runBlocking()
,您可以依賴它,並從JVM目標和本機目標之間共享的源集中呼叫runBlocking(),因為它會匹配庫的concurrent
源集中的“目標籤名”。
只需要指定一次依賴
從現在開始,不需要在共享和平臺相關的源集中對同一庫指定不同變體的依賴,而應該在共享源集中僅指定一次依賴關係。
不要使用有特定平臺字尾的kotlinx庫工件名稱,例如-common
,-**native**
或類似名稱,因為它們已不再受支援。請使用庫的基本工件名稱取而代之,在上面的示例中,其名稱為kotlinx-coroutines-core
。但是這個更改目前不影響stdlib
和kotlin.test
庫(stdlib-common
和test-common
);它們被安排在之後。
如果只需要特定平臺的依賴,則仍然可以使用標準庫和kotlinx庫的平臺特定變體,字尾為-jvm
或-js
,例如kotlinx-coroutines-core-jvm
。
在分層結構中使用native庫
你可以在多個native目標之間共享的源集中使用平臺相關的庫,例如Foundation
,UIKit
或posix
。這可以幫助你共享更多的native程式碼,而不受平臺特定的依賴限制。
無需任何步驟,這一切都會自動完成。 IntelliJ IDEA將幫助你檢測可在共享程式碼中使用的通用宣告。
但是請注意,存在一些限制:
- 該方法僅適用於共享給平臺特定源集之間的native源集。而不適用於共享給更高層級源集的native源集。
- 例如,如果你有一個
nativeDarwinMain
,它是watchosMain
和iosMain
的父級,其中iosMain
有兩個子級iosArm64Main
和iosX64Main
,則平臺相關的庫只能用於iosMain
,而不能用於nativeDarwinMain
。 - 該方法僅適用於Kotlin/Native定製的互操作庫。
詳細瞭解更多技術細節.
如何使用
要在共享源集中啟用平臺相關庫,請將以下內容新增到gradle.properties
中:
分享分層架構的反饋
請注意,分層專案結構目前處於技術預覽階段,並且仍在開發中。你可以檢視我們將要解決的已知問題,其中一些已有解決方案。
歡迎在Kotlin Slack的#multiplatform頻道中尋求幫助,並將錯誤報告給我們的問題跟蹤器 YouTrack。這是一項複雜而重要的特性,因此你的反饋將特別有用!
多平臺專案中要求Gradle 6.0或更高版本
從Kotlin 1.4-M2開始,所有多平臺專案將要求Gradle版本為6.0及以上。請確保為用到kotlin-multiplatform
外掛的專案升級Gradle。
更靈活的專案嚮導
透過使用新的更靈活的Kotlin專案嚮導,你可以在同一個地方輕鬆地建立和配置不同型別的Kotlin專案,包括多平臺專案,這在沒有UI的舊版本是難以想象的。
以前,你可以從不同位置提供不同的配置來建立Kotlin專案。現在只有一個地方可以做到這一點,它保證了簡潔而又不失靈活:
- 選擇專案模板,具體取決於你要執行的操作。
- 選擇構建系統——Gradle(Kotlin或Groovy DSL),Maven或IntelliJ。該向導僅顯示所選專案模板支援的構建系統。
- 在主介面上預覽專案結構。
然後,你可以完成建立專案,或者(可選)在下一個介面上配置專案:
- 新增/刪除專案模板所支援的模組和目標。
- 配置模組和目標設定,例如目標JVM版本,目標模板和測試框架。
- 設定模板間的依賴關係:
- iOS和多平臺模組
- Android和多平臺模組
- JVM模組
未來我們將透過新增更多配置選項和模板來使Kotlin專案嚮導更為靈活。
如何使用
- 安裝1.4-M2 Kotlin外掛。
- 在IntelliJ IDEA中點選File | New | Project。
- 在左側的皮膚中選擇Kotlin (Experimental Wizard)。
- 建立你的新Kotlin專案。
顯式API模式:統一且描述清晰的API
我們正在引入一種新的編譯器模式,以幫助庫作者建立一致且描述良好的API。在這種顯式的API模式下,編譯器會對庫的公共API宣告進行額外的檢查:
- 如果是預設可見性公開的公共API,則(API)宣告必須包含可見性修飾符。這有助於確保不會在無意間公開為public。
- 對於public API公開的屬性和函式,需要明確其型別。這樣可以確保API的使用者知道他們要用到的API成員型別。
根據你的配置,檢查後會發出錯誤(strict 模式)或警告(warning模式)。
我們計劃將來增加更多檢查,以改善你編寫程式碼庫的體驗。你可以在KEEP中瞭解有關的更多資訊。但是你已經可以嘗試顯式API模式並與我們分享你的反饋。
要在顯式API模式下編譯模組,請在Gradle構建指令碼中新增以下配置:
kotlin { explicitApi() // for strict mode // or explicitApiWarning() // for warning mode }在Groovy中,你可以使用這樣的語法:
當使用命令列編譯器時,請在-Xexplicit-api
編譯器選項中使用strict
或warning
:
Kotlin/Native支援掛起函式及其他改進
在該預覽中,Kotlin終於支援Swift和Objective-C中的掛起函式了,目前僅涵蓋了基本場景。我們一直在努力為Swift和Objective-C應用程式提供協程的完整功能。除此之外,我們準備介紹Kotlin/Native的效能及穩定性方面的一些工作成果。
Kotlin支援Swift和Objective-C的掛起函式
我們將繼續擴充套件Swift和Objective-C程式碼中對Kotlin關鍵功能的支援。之前版本已知的其中一個缺點是它們不完全支援Kotlin協程:沒有為Swift或Objective-C程式碼提供掛起函式。
在M2預覽中,我們很高興為Swift和Objective-C中的掛起函式提供了基本支援。現在,當你將Kotlin模組編譯成Apple框架時,其中的掛起函式可以作為帶有回撥的函式使用(Swift/Objective-C術語中的completionHandler
)。如果在生成的框架標頭檔案中具有此類函式,則你可以在Swift或Objective-C程式碼中呼叫它們,甚至重寫它們。
例如,當你編寫這樣一個Kotlin函式:
…然後你可以在Swift上如此呼叫:
請注意在M2預覽中,你只能在主執行緒中呼叫掛起函式。
透過gutter圖示執行Kotlin/Native程式碼
之前你只能在Terminal中執行Kotlin/Native程式碼,也可以在IntelliJ IDEA中透過Gradle任務執行。而現在,你可以方便地使用gutter圖示去執行,就像其他Kotlin程式碼一樣。
C互操作性的效能改進
在提高Kotlin/Native效能的範圍內,我們重新設計了C互操作庫的構建方式。 (這些庫是允許你在Kotlin程式碼中使用C和Objective-C庫宣告的工件。)這些變化雖然是肉眼不可見的,但可以感受到效能的提高和工件體積的減小:新工具的生成速度是以前的4倍,工件的大小是以前的25%到30%!
使用interop庫現在也更快,因為在Kotlin 1.4-M2用C interop編譯Kotlin專案花費的時間更少。
更穩定的編譯器快取和啟用Gradle守護程式
在1.3.70中,我們引入了兩個新功能來提高Kotlin/Native的編譯效能: 快取專案依賴和在Gradle守護程式中執行編譯。這些仍在完善中,因此部分情況下可能會遇到不穩定的問題。
感謝你們的反饋,我們已設法解決了許多問題並提高了這些功能的整體穩定性。因此,如果你遇到了問題,或者沒有機會嘗試最新版本的Kotlin/Native,現在可以嘗試一下了。
Kotlin/JS的改進
在1.4-M2中,Kotlin針對JavaScript目標的Gradle命名規範與其他Kotlin目標的規範更加相似了。它還預設增加了對編譯器設定更細粒度的控制,@JsExport
註解通用化,以及透過webpack啟用了CSS支援。
Gradle DSL的變動
命名變更
為了與其他Kotlin目標更加匹配,我們改動了Kotlin/JS Gradle一些常用配置的名稱。而對於1.4-M2中Kotlin/JS Gradle專案的預設配置塊,以下說明了我們所做的兩個命名更改:
target
變更為js
,這與Kotlin多平臺外掛的語法一致。- Kotlin 1.4-M1中引入的
produceExecutable()
變更為binaries.executable()
,使其與Kotlin/Native的命名一致。
如果你想進一步瞭解binaries.executable()
的功能,請參閱1.4-M1博文的“ Kotlin/JS | Gradle DSL的變化”。
各個專案的編譯設定
在Kotlin 1.4-M1,我們首先引入的新IR編譯器後端,具有DCE最佳化,TypeScript宣告預覽等功能,其中包含一個在gradle.properties
中的設定,可在預設,IR和同時啟用的編譯器模式之間切換。 M2直接從Gradle配置中引入了對每個專案所使用的編譯器模式更細粒度的控制。
要在不同的編譯器模式之間切換,請將編譯器型別傳遞給Gradle構建指令碼的js
函式。例如:
像這樣為專案設定的編譯器型別會覆蓋gradle.properties
中指定的預設設定。
Gradle支援Webpack的CSS載入器
由於Kotlin/JS Gradle外掛預設情況下使用webpack為瀏覽器建立構件,因此可以自定義許多設定。雖然可以直接修改用於構建專案的webpack配置檔案來更改所有選項,但我們希望能透過Gradle DSL直接訪問最常用的設定項。
Kotlin 1.4-M2預設為針對瀏覽器的專案啟用webpack的css-loader
。這意味著,在大多數情況下,無需任何其他配置即可新增CSS和包含樣式表的依賴到專案中。以前,你可能會遇到諸如Module parse failed: Unexpected character '@' (14:0)
之類的錯誤。
如果要調整CSS整合的行為,可以透過js.browser.webpackTask.cssSettings
進行調整。
透過cssSettings.enabled
,你可以決定專案是否啟用css-loader
(預設情況下啟用)。
透過cssSettings.mode
,可以指定遇到CSS時的行為。其候選值如下:
"inline"
(預設):樣式將被新增到全域性<style>
標記中。"extract"
:樣式將被提取到單獨的檔案。然後可以被包含在HTML頁面中。"import"
:樣式作為字串處理。如果你需要在程式碼中訪問CSS(例如val styles = require("main.css")
),這將很有用。
如果要對同一專案使用不同的模式,則可以使用cssSettings.rules
。在這裡,你可以指定一個KotlinWebpackCssRules
列表,每個列表定義一個模式以及包含和排除的規則。如果你想了解更多有關這些模式的資訊,請查閱webpack文件中的包含和排除規則。
自定義模組名
現在,你可以直接在Gradle構建指令碼中改變JavaScript的模組名稱:
這將影響到在build/js/packages/myModuleName
中生成的模組名稱,包括相關的.js
和.d.ts
檔名。請注意,這不會影響Webpack在build/distributions
中的輸出。要更改webpacked檔案的名稱,可以使用js.browser.webpackTask.outputFileName
。
通用程式碼的@JsExport
註解
@JsExport
註解現可在通用程式碼中使用,該註解在IR編譯器後端啟用時從JavaScript或TypeScript中生成頂級宣告。這避免了引入自定義註解和型別別名,並鋪平了多平臺Kotlin專案更便捷構建JavaScript庫的道路。
其他體驗改進及重要修復
- 用於瀏覽器和nodejs目標的常規Gradle任務現被劃分到單獨的任務組中。當透過
./gradlew tasks --all
列出所有任務時,kotlin browser
和kotlin node
組將被顯示到IntelliJ IDEA的Gradle工具視窗中。 - 現在,在為node.js目標執行測試時,偵錯程式可以正確地在斷點處停止了。
- 對於
同時使用兩種編譯模式
的專案和庫,現在能正確處理klib的依賴了。
相容性
請注意,在某些極端情況下,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-M2
- kotlinx.coroutines版本:1.3.7-1.4-M2
- kotlinx.serialization版本:0.20.0-1.4-M2
- ktor版本:1.3.2-1.4-M2
在這裡檢視有關發行版的更多細節和相容庫列表。
分享你的反饋
如果你發現錯誤並向我們的問題跟蹤器進行報告,我們表示非常感謝。我們嘗試在最終發行版前解決所有重要問題,這意味著無需等到下一個Kotlin發行版你的問題便能得到解決。
如果你有任何疑問並想參與討論,歡迎加入Kotlin Slack (在這裡獲得邀請)的#eap頻道。在該頻道中,你還可以獲取有關新預覽版的通知。
Let’s Kotlin!
其他貢獻者
同樣感謝提交的PR合併到該版本中的所有其他貢獻者:
- Toshiaki Kameyama
- Victor Turansky
- Jinseong Jeon
- Steven Schäfer
- Juan Chen
- Mark Punzalan
- Kristoffer Andersen
- Mads Ager
- Nick
- Polina Koval
- Konstantin Virolainen
- n-p-s
- Jiaxiang Chen
- Matthew Gharrity
- Martynas Sateika
- Nadezhda Petelimova
- Philippe Ombredanne
- Pierre-Luc Carmel Biron
- Kevin Bierhoff
- Scott Weber
- Miguel Serra
- Ivan Gavrilovic
- Irene Dea
- Harry
- Stanislav Ruban
- Brian Plummer
- Adam McNeilly