亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于Kotlin的自動類型轉(zhuǎn)換詳解

 更新時間:2020年09月15日 09:55:51   作者:Dexlind  
這篇文章主要給大家介紹了關(guān)于Kotlin的自動類型轉(zhuǎn)換的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

Kotlin 1.4 正式版在好早以前就已經(jīng)發(fā)布了。關(guān)于那些“看得見”的新特性,比如SAM轉(zhuǎn)換、參數(shù)列表末尾的可選逗號什么的,已經(jīng)有無數(shù)文章介紹過了。所以本文打算介紹一些可能是鮮為人知的、Kotlin 官方團隊偷偷塞進 1.4 的新特性。

不過單獨講這些東西會顯得文章太過單薄,于是我打算把其他相似的東西拉一起湊湊字數(shù)。

本文使用的 Kotlin 版本為 Kotlin 1.4。

本文要講的東西

看題目就知道了,Kotlin 里自動類型轉(zhuǎn)換(automatic type conversion)。這里講的不是 「把一個 String 轉(zhuǎn)成 Any,再轉(zhuǎn)成 String」 這種和子類型有關(guān)的東西,當然也不是 Smart Cast,而是兩個不相容的類型之間的轉(zhuǎn)換,比如說 Int 轉(zhuǎn)成 Long,如下文所示。

數(shù)值轉(zhuǎn)換

一般地,在 Kotlin 里我們不能像 Java 一樣直接把一個 Int 類型的東西賦值給 Long 類型的變量,因為它們之間并不具有子類型關(guān)系。像下面這樣會得到一個編譯錯誤:

val int: Int = 555
val long: Long = int // 編譯錯誤!
println(long)

你需要調(diào)用標準庫提供給你的那些 toXXX 函數(shù)把數(shù)值轉(zhuǎn)換成其他類型的數(shù)值。

val int: Int = 555
val long: Long = int.toLong() // OK
println(long)

Kotlin 官方團隊曾經(jīng)表示過不喜歡隱式(implicit)的東西,關(guān)于數(shù)值的隱式類型轉(zhuǎn)換也包括在內(nèi)。這就導致了使用 Kotlin 在進行一些關(guān)于數(shù)值方面的操作時,有時候會寫出一些看起來無比蛋疼的代碼。

Bennyhuo:就是有時候?qū)扅c兒計算比較多的代碼,滿篇的 toFloat toDouble。

不一般地,我們可以使用 @Suppress 來搞事:

val int: Int = 233
@Suppress("TYPE_MISMATCH")
val long: Long = int
println(long) // 233

這個代碼是可以跑起來的,而且你真的可以從字節(jié)碼里看到那個把 Int 轉(zhuǎn)成 Long 的指令 I2L。

不過我不確定 Kotlin 的其他 target 是否能這樣用,我也不保證這樣寫完全不會出問題。(這里是關(guān)于 @Suppress 的免責聲明,請讀者自行腦補)

SAM Conversion

SAM 轉(zhuǎn)換也是一種自動類型轉(zhuǎn)換。它把一個 lambda 表達式(具有函數(shù)類型)轉(zhuǎn)成某個具體的接口類型。

fun interface ISome {
 fun some()
}

fun useSome(some: ISome) {}

useSome { println("some") }

在我的另一篇文章里有更詳細的介紹。

如果讀者不同意這個說法,可以選擇跳過本小節(jié)內(nèi)容。

Coercion to Unit

我們都知道 Kotlin 的 lambda 表達式是使用里面最后一個表達式的值來作為 lambda 的返回值的。比如這樣:

val block = { "yeah" }

block 的類型是 () -> String。

然后我們來看看這樣的情況:

fun test(block: () -> Unit) {
 println(block())
}

test { "yeah" } // 輸出 Unit

相信很多人都熟悉這樣的寫法。

在某些初學者的眼里這看起來像是把一個 () -> String 類型的 lambda 傳給了需要 () -> Unit 類型的函數(shù)。

這就是 coercion to unit,一個很久以前就存在的特性,可以理解為編譯器自動幫你在 lambda 表達式的最后加了一行 Unit,把本來應(yīng)該是() -> String 類型的 lambda 變成了 () -> Unit 類型。

在 Kotlin 1.4 版本,這個特性得到了進化,你甚至可以這樣寫:

fun test(block: () -> Unit) {
 println(block())
}

fun some(): String {
 return "str"
}

// 需要 Kotlin 1.4 版本
test(::some) // 輸出 Unit

編譯器幫你把 () -> String 類型的函數(shù)引用轉(zhuǎn)成了 () -> Unit。

Unit Conversion

警告:這是一項未完成的特性!

添加編譯器參數(shù) -XXLanguage:+UnitConversion,你就開啟了一個 Kotlin 官方團隊偷偷塞進 1.4 版本的未完成的新特性。

這個特性允許你寫出這樣的代碼:

fun test(block: () -> Unit) {
 println(block())
}

fun some(block: () -> String) {
 test(block) // 這里是重點
 // 如果你不加那個編譯器參數(shù),會報錯
}

fun main() {
 some { "str" }
 // 理論上會輸出 Unit
}

在函數(shù) some 里把一個 () -> String 傳給了 test 函數(shù),可以看出來這個特性其實和 coercion to unit 是差不多的。

理論上這樣的代碼運行時會輸出 Unit,但是目前由于該特性的代碼生成沒寫好,得不到預(yù)期的結(jié)果。

另外,在開啟了這個特性后,() -> String 并不會成為 () -> Unit 的子類型,它們依然是兩個不相容的類型。

Suspend Conversion

警告:這是一項未完成的特性!

這是本文要介紹的第二個 Kt 官方團隊偷偷塞進 1.4 版本的未完成的新特性。

比如說我們有這樣的一個函數(shù):

fun test(f: suspend () -> Unit) {
 // do something with f
}

我們可以這樣調(diào)用它:

test { println("hi") } 

但是這樣不行:

val f = { println("hi") }
test(f) // 編譯錯誤

編譯器會告訴你類型不匹配,f 是 () -> Unit 類型,test 函數(shù)需要 suspend () -> Unit 類型的參數(shù)。

當你添加了編譯器參數(shù) -XXLanguage:+SuspendConversion,就可以讓上面的代碼通過編譯。

也就是說這個特性可以幫你把普通函數(shù)類型的值轉(zhuǎn)成 suspend 函數(shù)類型。

當然由于這是未完成的功能,即使可以通過編譯,但是跑起來還是會炸。

這個特性或許會在 Kotlin 1.5 版本完工,但請不要抱有期待。

結(jié)尾

我并不想討論「為什么要加這種奇怪的特性」之類的話題。

不可否認的是,在有限的程序員生涯中,這些新特性可能一次也用不上。上面提到的問題也都有相應(yīng)的 workaround,不需要新特性也可以寫出等價的代碼,就是沒有那么優(yōu)雅罷了(

到此這篇關(guān)于關(guān)于Kotlin自動類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Kotlin自動類型轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論