Kotlin 1.4-M2正式釋出

kotliner發表於2020-06-16

時光飛逝,今天我們想向你展示Kotlin 1.4的部分強大的預覽特性。在Kotlin 1.4正式釋出之前,請了解並嘗試Kotlin 1.4-M2。

kotlin-1.4-M2

我們很感謝試用了Kotlin 1.4首個預覽版並反饋以幫助Kotlin變得更完善的人!

也非常感謝嘗試了在上一篇博文所提到的*Kotlin 1.4-M2’s標準庫的改動的人。

在這篇博文中,我們將重點介紹1.4-M2中可用的新特性和關鍵改進:

你可以在更新日誌中找到完整的變更列表。我們同樣非常感謝其他貢獻者

如果你能嘗試預覽版反饋,我們將非常感激。

多目標分層專案架構中共享程式碼

隨著專案分層架構的支援,你可以在多平臺專案的多個目標中共享程式碼。

在此之前,多平臺專案中的程式碼要麼被放入到平臺的指定源集中(僅限於一個目標,並且不能被任何其他平臺複用),要麼放入到公共源集中,例如commonMaincommonTest,在專案中的所有平臺之間共享。在公共源集中,你只能呼叫被expect宣告的平臺獨立實現的actualAPI。

雖然這讓在所有目標之間共享程式碼變得容易,但是在目標之間的共享卻並不容易,尤其複用通用邏輯和第三方API的相似目標。

例如,在針對iOS的典型多平臺專案中,有兩個與iOS相關的目標:一個針對iOS ARM64裝置,另一個針對x64模擬器。它們具有獨立的平臺指定的源集,但是在實踐中,幾乎不需要為裝置和模擬器使用不同的程式碼,並且它們的依賴非常相似。因此可以在它們之間共享iOS平臺特定的程式碼。

顯然,在此設定中,希望能有兩個iOS目標的共享源集,並且Kotlin/Native程式碼仍可以直接呼叫iOS裝置和模擬器共通的任何API。

ios-source-sets

現在你可以在分層專案架構來實現這一點,它會根據呼叫方的目標來推斷和調整每個源集中可用的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。但是這個更改目前不影響stdlibkotlin.test庫(stdlib-commontest-common);它們被安排在之後。

如果只需要特定平臺的依賴,則仍然可以使用標準庫和kotlinx庫的平臺特定變體,字尾為-jvm-js,例如kotlinx-coroutines-core-jvm

在分層結構中使用native庫

你可以在多個native目標之間共享的源集中使用平臺相關的庫,例如FoundationUIKitposix。這可以幫助你共享更多的native程式碼,而不受平臺特定的依賴限制。

無需任何步驟,這一切都會自動完成。 IntelliJ IDEA將幫助你檢測可在共享程式碼中使用的通用宣告。

但是請注意,存在一些限制:

  • 該方法僅適用於共享給平臺特定源集之間的native源集。而不適用於共享給更高層級源集的native源集。
  • 例如,如果你有一個nativeDarwinMain,它是watchosMainiosMain的父級,其中iosMain有兩個子級iosArm64MainiosX64Main,則平臺相關的庫只能用於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的舊版本是難以想象的。

project-wizard-1

以前,你可以從不同位置提供不同的配置來建立Kotlin專案。現在只有一個地方可以做到這一點,它保證了簡潔而又不失靈活:

  1. 選擇專案模板,具體取決於你要執行的操作。
  2. 選擇構建系統——Gradle(Kotlin或Groovy DSL),Maven或IntelliJ。該向導僅顯示所選專案模板支援的構建系統。
  3. 在主介面上預覽專案結構

然後,你可以完成建立專案,或者(可選)在下一個介面上配置專案

  1. 新增/刪除專案模板所支援的模組和目標
  2. 配置模組和目標設定,例如目標JVM版本,目標模板和測試框架。
project-wizard-2
  1. 設定模板間的依賴關係
    • iOS和多平臺模組
    • Android和多平臺模組
    • JVM模組
project-wizard-3

未來我們將通過新增更多配置選項和模板來使Kotlin專案嚮導更為靈活。

如何使用

  1. 安裝1.4-M2 Kotlin外掛
  2. 在IntelliJ IDEA中點選File | New | Project
  3. 在左側的皮膚中選擇Kotlin (Experimental Wizard)
  4. 建立你的新Kotlin專案。

顯式API模式:統一且描述清晰的API

我們正在引入一種新的編譯器模式,以幫助庫作者建立一致且描述良好的API。在這種顯式的API模式下,編譯器會對庫的公共API宣告進行額外的檢查:

  • 如果是預設可見性公開的公共API,則(API)宣告必須包含可見性修飾符。這有助於確保不會在無意間公開為public。
  • 對於public API公開的屬性和函式,需要明確其型別。這樣可以確保API的使用者知道他們要用到的API成員型別。
explicity-api-mode

根據你的配置,檢查後會發出錯誤(strict 模式)或警告(warning模式)。

我們計劃將來增加更多檢查,以改善你編寫程式碼庫的體驗。你可以在KEEP中瞭解有關的更多資訊。但是你已經可以嘗試顯式API模式並與我們分享你的反饋。

要在顯式API模式下編譯模組,請在Gradle構建指令碼中新增以下配置:

kotlin { explicitApi() // for strict mode // or explicitApiWarning() // for warning mode }

在Groovy中,你可以使用這樣的語法:

當使用命令列編譯器時,請在-Xexplicit-api編譯器選項中使用strictwarning

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程式碼一樣。

native-gutter-icon

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 browserkotlin node組將被顯示到IntelliJ IDEA的Gradle工具視窗中。
  • 現在,在為node.js目標執行測試時,偵錯程式可以正確地在斷點處停止了。
  • 對於同時使用兩種編譯模式的專案和庫,現在能正確處理klib的依賴了。

相容性

請注意,在某些極端情況下,Kotlin 1.4不向後相容1.3。語言委員會仔細審查了所有此類情況,並將其列入“相容性指南”(類似於這個)。當前你可以在YouTrack中找到這份列表。

正式釋出前注意事項

請注意,向後相容性不保證包含預發行版本。其特性和API可能在後續版本中更改。當到達最終RC時,編譯器將禁止所有預發行版本產生的二進位制檔案,並且將需要你重新編譯1.4‑Mx編譯過的所有內容。

如何嘗試最新的特性

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

IntelliJ IDEAAndroid Studio,你可以更新Kotlin外掛到1.4-M2版本。操作指南

如果要在現有專案使用預覽版,則需要在Gradle或Maven中為預覽版本配置構建.

你可以在Github發行頁下載命令列編譯器

你可以使用隨版本發行的的以下版本:

這裡檢視有關發行版的更多細節和相容庫列表。

分享你的反饋

如果你發現錯誤並向我們的問題跟蹤器進行報告,我們表示非常感謝。我們嘗試在最終發行版前解決所有重要問題,這意味著無需等到下一個Kotlin發行版你的問題便能得到解決。

如果你有任何疑問並想參與討論,歡迎加入Kotlin Slack (在這裡獲得邀請)的#eap頻道。在該頻道中,你還可以獲取有關新預覽版的通知。

Let’s Kotlin!

其他貢獻者

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

相關文章