Kotlin 1.3 RC 來啦:快遷移您的協程程式碼吧!

bennyhuo發表於2018-09-20

現在我們非常自豪地釋出 Kotlin 1.3-RC,這將是 1.3 之前的最後一個預覽版本。這個版本修復了絕大多數的新功能相關的關鍵 bug,除此之外,還有一些其他的更新值得一提:

  • Ktor 的 API 已經完善,期待大家的使用體驗和反饋。Ktor 是一個基於協程的框架,使用它我們可以優雅的構建 Web 應用、Http 服務、移動應用和網頁。
  • 所有的新專案都已經採用官方程式碼規範 ,我們也非常鼓勵大家也這樣做。
  • 程式入口 main 函式支援無引數的形式,它也可以是一個 suspend 函式。
  • 1.2.50 引進的對指令碼的支援如今也得到了更新和完善。
  •  kotlinx.serialization 的外掛已經合入 Kotlin 主工程,並且被整合到編譯器外掛當中。
  • 我們廢棄了一些標準庫當中的 API,當然對於過去就已經廢棄的 API 這次我們直接報錯。
  •  org.jetbrains.annotations 當中的註解從標準庫中獨立出來,成為一個新的構件方便開發者自由選擇依賴。

RC

感謝來自社群的貢獻者們,這個版本合入了以下開發者的程式碼提交:Toshiaki KameyamaCuihtlauac ALVARADOkenji tomitaMartin PetrovDenis VnukovshirajiPaul de VriezeRaluca SauciucIvan Gavrilovic.

完整的更新內容請參見 更新日誌

如果您在試用 1.3 版本的新功能和特性時遇到了問題,請及時與我們聯絡,我們非常期待和感謝您的反饋。Kotlin 1.3.0 的最終版本即將到來,請抓緊時間分享您的使用體驗吧!

2018 Kotlin 開發者大會

Kotlin 開發者大會即將召開!對於不方便現場參加大會的開發者,我們將提供現場直播以及資料共享。請您 註冊 以便得到我們的直播通知。

是時候遷移您的協程程式碼了

從 Kotlin 1.3 開始,協程將進入穩定狀態。鑑於此,大家可以在 1.3.0 釋出之後就可以立刻馬上遷移協程程式碼了,我們也會提供相應的工具幫助大家完成這項工作。

對於kotlinx.coroutines 來說:

  1. 您需要在實驗狀態下(experimental) 更新到最新的版本,當前最新版是 0.26.1(Kotlin 1.3 釋出之前也可能會有少量的更新)
  2. 將您的專案直接切換到 Kotlin 1.3,IDE 的工具會幫助您完成遷移,目前來說就是切換到 0.26.1-eap13,這個版本是基於 Kotlin 1.3 構建的。這個遷移工作主要是去掉包名當中的 experimental。
  3. 待 Kotlin 1.3 正式發版之後,kotlinx.coroutines也將會發布 1.0 版,屆時您只需要更新版本號,重新編譯程式碼即可。

需要注意的是,kotlinx.coroutines 1.0 將會丟棄所有之前的 0.x 版本中的廢棄的介面和宣告,與 0.x-eap13 版本二進位制不相容,因此在切換正式版之前就需要把您程式碼中使用過時 API 的程式碼進行整理。

kotlinx.coroutines也會有一些 API 被標記為“unstable”,它們將會在後續的更新中得到完善。儘管使用這些“unstable”的 API 需要特定的選項配置,但核心 API 都將在 1.0 最終確定並保證如同 Kotlin 標準庫一樣在後續更新中後向相容。

不需要引數的 “Main” 函式

就像其他很多語言那樣,我們從 1.3 開始允許 “main” 函式的字串陣列引數可選,如此一來,經典的 “Hello, World!” 在 Kotlin 當中就更短啦:

可掛起的 “main” 函式

“main”函式不僅引數可選,還可以是 “suspend”,換句話說,您再也不需要使用 “runBlocking” 就可以在 “main”函式當中直接呼叫其他 “suspend” 函式了:

Ktor 框架

協程終於“畢業”,所以媽媽再也不用擔心我們釋出我們自己的非同步框架了。為此,我們做了很多工作,其中最值得一提的是 Ktor –
一個用於連線應用的非同步框架。它包括一個跨平臺的 HTTP 客戶端和一個基於 JVM 的 HTTP 服務端。

客戶端目前已經支援 JVM/Android 和 iOS,後續也將支援更多的平臺包括 JS(瀏覽器)和各種各樣的 native 平臺。服務端則執行在 JVM 上面,您可以使用 Netty、Jetty 以及其他類似於 Tomcat 的 servlet 容器。

Ktor 測試充分、易於上手、效能優越,請參考 https://ktor.kotlincn.net/。它的 0.9.5-rc13 相容 Kotlin 1.3-RC,0.9.5 則相容 Kotlin 1.2.70。

與我們一起打造我們自己的非同步框架吧,這樣我們就可以讓我們的程式碼可讀性和可維護性得到飛躍!

編碼規範

官方程式碼規範文件已經推出了一些時日,是時候做進一步的工作了:從 Kotlin 1.3 開始,使用 IntelliJ IDEA 建立的所有新專案都將應用這份程式碼規範。

雖然我們建議大家透過提交 .idea/codeStyles 到 VCS 來共享程式碼風格,但不少開發者的內心卻是拒絕的。因此我們引入了一個 Gradle 的屬性 kotlin.code.style,可以設定值為 official 或 obsolete。如此一來,其他 IDE 也就可以享受到這一特性了。

如果您想要使用原來的程式碼風格,只需要設定 kotlin.code.style=obsolete以免後續遇到遷移上的麻煩。這個屬性在 Maven 當中也適用。

指令碼

這個版本對指令碼的支援做了很多最佳化改進,其中最重要的就是重新打造的更簡潔更清爽的 API。儘管指令碼支援的特性可能還需要一段時間的實驗,但目前看來 API 將基本定型。其中的一些無用的和尚未實現的 API 被移除,等時機成熟,在後續的版本當中我們有意對絕大多數移除的 API 進行召回。

為了簡化指令碼專案的構建和工具指令碼的依賴,我們提供了一個新的元件 kotlin-main-kts。這個簡單的 jar 包提供了一些指令碼的定義和基本的 Maven 構建解析器,有了它,我們就可以寫出下面的指令碼了:

執行時只需要將 kotlin-main-kts.jar 新增到 classpath:

kotlinc -cp <path/to/kotlin-main-kts.jar> -script sample.main.kts

指令碼支援方面還有其他的許多問題修復和功能提升,建議大家透過案例多多嘗試,並積極反饋~

完整的 Kotlin 指令碼提案以及當前的實現狀態可以參考 KEEP-75

實驗狀態的序列化外掛

從這個版本開始,以前獨立的外掛 kotlinx.serialization 將合併到 Kotlin 的編譯器外掛當中。

儘管在 Kotlin 1.3 當中它將仍然保持實驗狀態,但這並不影響它在生產環境中的使用,它是足夠成熟和穩定的,我們也非常期待大家的反饋。相關提案請參見:KEEP-149,如果有什麼意見和建議,歡迎開 issue 討論。

內聯類 Inline classes

我們調整了內聯類的二進位制表示,目的是讓它更加緊湊、更與時俱進,同時也修復了一些關鍵的問題。Kotlin 反射也可以正確的處理內聯類,並完成自動的拆箱和裝箱。

標準庫

相比之下,這個版本更關注正式發版前的程式碼整理而不是新功能。

可空型別的 hashCode()

當實現一個泛型容器類時,通常我們需要獲取元素的雜湊值,而元素通常也可以為 null,因此過去我們需要使用 ?. 以及 elvis 運算子來解決這個問題:

element?.hashCode() ?: 0.

現在我們有了 Any?.hashCode(),對於任意元素無論是否為空,都可以如此呼叫: element.hashCode()

Range 迭代時的元素空檢查

value 是可空型別,同時 Range 是 Iterable且範圍較大時,在 value in from..to 中進行空檢查將非常耗時。這種情況下,範圍的包含關係判斷會退化成 Iterable<T>.contains(T),這樣整個過程就成了 Iterable 的遍歷(直到元素找到或者確定找不到為止)。

為了解決這個問題,我們引入了一系列 contains 的過載,以 IntRange.contains(element: Int?) 為例,它會先檢查引數 element 是否為空,緊接著執行一個快速的包含關係判斷:

SuccessOrFailure 更名為 Result

我們在之前的 Kotlin 1.3 預覽版中提供了一個封裝 Kotlin 函式結果的類 SuccessOrFailure,經過 review 和社群反饋,更名為Result。這個類目前主要應用於協程,作為Continuation.resumeWith的引數。Kotlin 中有許多設計線索可用於將來擴充套件錯誤處理,這將要求我們重新設計使用此Result類作為返回型別的程式碼的語義。因此,為避免將來的設計會破壞此類程式碼,Kotlin 1.3 編譯器會對於這類宣告報錯,當然標準庫函式的一些情況則是例外,因為這些函式專門用於對 Result 型別進行操作。詳細請參見 KEEP-127

Sequence 和 iterator 的建立函式以及他們的 scope 類

在協程 API 最終確定下來之前,我們需要對 buildSequence 和 buildIterator 進行重新命名。這些名字主要是為了與  buildString 以及一些構造集合框架型別的函式提議保持一致。然而,我們最近意識到 sequence 和 string 的建立函式在懶載入方面差異較大,所謂的一致性實際上並不是很合理。

這些建立函式從 buildSequence { } 和 buildIterator { } 更名為 sequence { } 和 iterator { }。引數的 receiver 類則從 SequenceBuilder 變更為 SequenceScope

這樣一來,Sequence 的建立程式碼將變成:

有符號整型轉無符號時符號位擴充套件到長整型

整型有符號到無符號轉換的處理方法與其他語言趨於一致,Int.toULong() 以及其他類似的函式在轉換時採用了符號位擴充套件到高位的做法,而不是 0 擴充套件,所以 (-1).toULong() 現在等於 ULong.MAX_VALUE (0xFFFF_FFFF_FFFF_FFFF) 而不是 UInt.MAX_VALUE (0x0000_0000_FFFF_FFFF).

註解成為獨立的構件

與編譯器一起釋出的標準庫不再包含 org.jetbrains.annotations 中的註解,這樣也可以與 Maven Central 中釋出的標準庫保持一致。這些註解現可以在 annotations-13.0.jar 和 mutability-annotations-compat.jar 當中找到。

廢棄整型、浮點型混合的區間包含運算子

前面我們提到對於可空型別的包含關係判斷會有問題,其實還有一個麻煩就是整型區間遇到浮點型引數這樣類似的情況。例如 3.14 in 1..3 是可以編譯執行的,但結果就有點兒尷尬了: true。我們廢棄了這樣的 contains 運算子過載,後面會逐漸移除它們。

其他廢棄的通知

對於過去就已經廢棄的 API,這次我們會提高它們的廢棄級別,對於使用這些 API 的程式碼,我們會直接報錯而不是警告。

這版要對 JS 標準庫中曾經廢棄的 API 下手的主要有:

  • jsClass函式
  • kotlin.Synchronized 和 Volatile 註解
  • kotlin.js.Math 函式
  • kotlin-test-js 當中 org.junit.Test 註解

如果這些您都不熟,那沒關係。否則的話,請儘快按照說明遷移您的程式碼。

在下一個版本也就是 1.4 當中,我們將要移除標準庫當中的 jQuery 型別的宣告,相應的功能將由 https://bintray.com/kotlin/js-externals/kotlin-js-jquery 提供。

命令列編譯器

這一版本支援我們選用另外的一種方式來透過檔案給編譯器傳參。除了使用 1.2.50 中引入的 -Xargfile=filename.txt,您也可以直接給 kotlinc 傳入 @filename.txt 這樣的引數,檔案內容將會被按行解析為引數。這樣將會方便使用 kotlinc 編譯大量的原始檔,同時也可以方便處理更長更復雜的檔案路徑。

這版中另一個要“畢業的”的實驗特性便是 1.2.50 引入的 progressive 編譯模式,我們可以透過 -progressive 來開啟這種模式。

如何嘗鮮

在 Maven/Gradle 專案中: 為構建指令碼和專案依賴新增 repository https://dl.bintray.com/kotlin/kotlin-eap。使用 1.3.0-rc-57 作為編譯器和標準庫的版本號。

在 IntelliJ IDEA 中: 在 Tools → Kotlin → Configure Kotlin Plugin Updates中,Update channel 中選擇 “Early Access Preview 1.3”,然後點選Check for updates

命令列編譯器可以在 Github release page 下載。

 try.kotlinlang.org: 在右下角的下拉選單中選擇編譯器的版本為 1.3‑RC 即可。

本文翻譯自官方部落格:Kotlin 1.3 RC is Here: Migrate Your Coroutines!

相關文章