11月16日 JetBrains 正式發布了 Kotlin 1.6.0,這個版本根據一些反饋,將上一版本中的一些實驗的語法特性進行了轉正。例如
- Sealed exhaustive whens
- Suspending functions as supertypes
- ...
Sealed exhaustive whens
當我們在 when 中使用諸如枚舉、密封類/接口等可窮舉類型時,某些情況下可能寫出不安全的代碼
sealed class Contact { data class PhoneCall(val number: String) : Contact() data class TextMessage(val number: String) : Contact() data class InstantMessage(val type: IMType, val user: String) : Contact()}復制代碼
如上,定義了三個子類的密封類
fun Rates.computeMessageCost(contact: Contact): Cost = when (contact) { // ERROR: when expression must be exhaustive is Contact.PhoneCall -> phoneCallCost is Contact.TextMessage -> textMessageCost }復制代碼
此時如果 case 后跟的是一個表達式, 則如果 case 分支沒有窮舉所有子類,編譯器會報錯
但是如果如果 case 后個的是一個語句,如下
fun sendAnnouncement(contact: Contact, announcement: Announcement) { when (contact) { is Contact.PhoneCall -> schedulePhoneCall(contact.number, announcement) is Contact.TextMessage -> sendTextMessage(contact.number, announcement) }}復制代碼
此時即使沒有窮舉所有子類,編譯器也不會報錯,這可能會造成不必要的bug
Kotlin 1.6 在這種情況下,編譯器會給出 Warning ,按計劃 1.7 之后 Warning 會改為 Error,強制開發者補齊所有分支邏輯,避免出現 Bug
Suspending functions as supertypes
Kotlin 中許多 API 都以函數類型作為參數。當你需要調用這些 API 時,需要傳入一個函數類型的實例。而當你想在實例中封裝一些可復用的邏輯時,可以使用函數類型作為父類創建子類。
但是這種做法目前不適用于掛起函數,你無法繼承一個 suspend
函數類型的父類
class C : suspend () -> Unit { // Error: Suspend function type is not allowed as supertypes }C().startCoroutine(completion = object : Continuation<Unit> { override val context: CoroutineContext get() = TODO("Not yet implemented") override fun resumeWith(result: Result<Unit>) { TODO("Not yet implemented") }})復制代碼
Kotlin 1.5.30 在 Preveiw 中引入了此特性,可以繼承一個 suspend 的函數類型
class MyClickAction : suspend () -> Unit { override suspend fun invoke() { TODO() }}fun launchOnClick(action: suspend () -> Unit) {}復制代碼
如上,你現在可以這樣調用 launchOnClick(MyClickAction())
。
1.6 中將此 feature 默認打開。
此外 1.6 還加入了其他一些新的語法特性,詳情可以參考:blog.jetbrains.com/kotlin/2021…
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/123972.html