Kotlin類型系統(tǒng)竟如此簡(jiǎn)單
Quote
在學(xué)習(xí) Kotlin 的過程中,對(duì) Kotlin 的類型系統(tǒng)產(chǎn)生了好奇,Kotlin 是否存在類似于 Java 中 Object 的公共基類?Kotlin 中是否也有類似于 Java 基礎(chǔ)類型這樣的單獨(dú)分支?在研究一番過后,博主發(fā)現(xiàn)相較于 Java,Kotlin 交出了更為滿意的答案,而且出乎意外地簡(jiǎn)單,只需要遵循簡(jiǎn)單的規(guī)則,便能理解整個(gè)類型系統(tǒng)。
Any
Any 等同于 Java 中的 Object 的概念,Any 在注釋中這么寫到:
The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
我們來簡(jiǎn)單驗(yàn)證下 Any 是一切的基類。
class Fruit fun main(args: Array<String>) { println(Fruit() is Any) }
在上面的代碼中,我們新建了一個(gè)類,然后構(gòu)造它的實(shí)例,看它是否為 Any,答案顯而易見地為 true。
我們?cè)诳匆恍?kotlin 中的基礎(chǔ)類型,也就是 Int、Double、Float、Byte 等等的父類是否也是 Any。
println(3.233F is Any) println(2 is Any)
答案也是true。這里額外地解釋下,Kotlin 并沒有 Java 中基礎(chǔ)類型和封裝類型差異化處理,也沒有拆箱和裝箱的處理?;A(chǔ)類型就是基礎(chǔ)類型,但它們也以Any作為父類。
Unit
再來看看 Unit 這個(gè) Kotlin 中的特殊東西。
/** * The type with only one value: the `Unit` object. * This type corresponds to the `void` type in Java. */ public object Unit { override fun toString() = "kotlin.Unit" }
在 kotlin 中每個(gè)函數(shù)一定是有返回值的。
這里說明一下概念,也將會(huì)在后續(xù)的章節(jié)里面再次提到。kotlin 為了這個(gè)一定有返回值這個(gè)概念,做了很多工作,但好處是非常明顯的,我們能夠以統(tǒng)一的視角來看待 kotlin 的函數(shù)。
Unit 這個(gè)概念表征著什么都不做,但什么都不做確實(shí)也是一種返回值。如果我們不做任何聲明,函數(shù)的返回值就是 Unit,表明我返回了一個(gè)什么都沒做的東西。
我們來驗(yàn)證一下,聲明一個(gè)空函數(shù),然后打印它。(在 Java 中會(huì)編譯不過)
fun justReturn() { } fun main(args: Array<String>) { print(justReturn()) }
結(jié)果輸出了kotlin.Unit,證明了返回值就是 Unit。
那么這里有一個(gè)疑問,就是 Unit 和 Any 什么關(guān)系?我們通過 is 關(guān)鍵字來看看。
fun main(args: Array<String>) { print(justReturn() is Any) }
恩恩,Unit 也是 Any 的子類!
Nothing
我們繼續(xù)延展下kotlin 中每個(gè)函數(shù)一定是有返回值的這個(gè)概念。前面我們看的是正常返回的情況,那如果程序發(fā)生異常,也會(huì)有返回值嗎?kotlin 對(duì)于這種情況,也是延續(xù)了一定有返回值這種概念。這個(gè)返回值叫做 - Nothing!
Nothing 意味著不可達(dá),程序?qū)嶋H運(yùn)行時(shí)不會(huì)產(chǎn)生任何一個(gè) Nothing 類型對(duì)象,啥?!這怎么理解。kotlin 一旦發(fā)現(xiàn)返回了 Nothing,會(huì)保證后面的代碼不再執(zhí)行。
所以 Nothing 常用于 throw 這樣異常退出的情況,這樣后續(xù)的代碼就不會(huì)被執(zhí)行。我們看看 kotlin 中自身的例子。
/** * Terminates the currently running process. * * @param status serves as a status code; by convention, * a nonzero status code indicates abnormal termination. * * @return This method never returns normally. */ @kotlin.internal.InlineOnly public inline fun exitProcess(status: Int): Nothing { System.exit(status) throw RuntimeException("System.exit returned normally, while it was supposed to halt JVM.") }
注意啦,我們?cè)倏纯?Nothing 在類型系統(tǒng)中的位置。Nothing 與 Any 相反,是一切類型的子類!也就是說 Nothing,是 Fruit、是 School、是 Money、也是 Any。Nothing 意味著不可達(dá)的狀態(tài),每一種類型都包含這種不可達(dá)的狀態(tài),因而這種狀態(tài) Nothing,是這些的子類。
注意上圖中 Nothing 所處的位置。
Nullable
kotlin 的一大殺手锏就是這個(gè)可空類型,一種類型后面加上?,這種類型就可以為空了。我們來看看引入可空類型過后,類型系統(tǒng)是怎樣的。
1、首先看看普通類和可空類型之間的關(guān)系。
class Fruit fun main(args: Array<String>) { print(Fruit() is Fruit?) }
答案是true,這里很好理解,兩者之間的區(qū)別在于是否可以為空,可以為空的自然而然是基類,不可為空的是可以為空下的一種派生。
2、Any 是否有可空類型
kotlin 最讓人欣賞的地方在于一個(gè)概念貫徹到底。Any 在 kotlin 中也是有可空類型的。感官上 Any? 是 Any 的父類,Any 是不可空類型的父類,所以 Any? 也是不可空類型的父類嗎?答案就是這樣的,我們來驗(yàn)證下。
class Fruit fun main(args: Array<String>) { print(Fruit() is Any?) }
3、Unit 是否有可空類型
是的,Unit 也有空類型 Unit?。但這是一個(gè)難理解的概念,其本身包含了兩個(gè)值 Unit 和 null。這是 kotlin 為了延續(xù)統(tǒng)一的概念,很少會(huì)有場(chǎng)景使用到,但咱們得清楚。
4、Nothing 是否有可空類型
Nothing 當(dāng)然也有可空類型 Nothing?,其本身有且僅有一個(gè)值 null,也就是說其就是 null。Nothing 本身不可達(dá),不會(huì)有任何一個(gè)實(shí)例,那就只能是 null 了。
我們來驗(yàn)證一下
fun main(args: Array<String>) { println(null is Nothing) println(null is Nothing?) println(null is Any) println(null is Any?) }
分別是 false、true、false 和 true。
總結(jié)
這里借用下 natpryce 的圖,大家看一下這張圖,這就是 kotlin 的類型系統(tǒng)。
咱們只需要理解一下幾點(diǎn),就完全弄明白 kotlin 類型系統(tǒng)。
- Any 和 Nothing 分別是所有對(duì)象的基類和子類。
- 可空類型是不可空類型的父類。
當(dāng)我們不清楚類型時(shí),對(duì)照上面兩個(gè)概念就能明白。
參考
- Mistaeks I Hav Made: A Whirlwind Tour of the Kotlin Type Hierarchy
- https://proandroiddev.com/nothing-else-matters-in-kotlin-994a9ef106fc
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Android RecyclerView詳解之實(shí)現(xiàn) ListView GridView瀑布流效果
RecyclerView 是Android L版本中新添加的一個(gè)用來取代ListView的SDK,它的靈活性與可替代性比listview更好2016-07-07Android實(shí)現(xiàn)QQ新用戶注冊(cè)界面遇到問題及解決方法
這篇文章主要介紹了Android實(shí)現(xiàn)QQ新用戶注冊(cè)界面遇到問題及解決方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09Android中EditText 設(shè)置 imeOptions 無效問題的解決方法
有時(shí)候我們需要在EditText 輸出完之后 需要在鍵盤出現(xiàn) 右下角變成“Go”或“前往 搜索時(shí);通常我們需要設(shè)置Android:imeOptions屬性,但是今天我發(fā)現(xiàn)設(shè)置了無效,下面給大家分享下解決方案2016-12-12Android App開發(fā)中RecyclerView控件的基本使用教程
這篇文章主要介紹了Android App開發(fā)中RecyclerView控件的基本使用教程,RecyclerView在Android 5.0之后伴隨著Material Design出現(xiàn),管理布局方面十分強(qiáng)大,需要的朋友可以參考下2016-04-04Android?app啟動(dòng)節(jié)點(diǎn)與上報(bào)啟動(dòng)實(shí)例詳解
系統(tǒng)的啟動(dòng)過程非常復(fù)雜,下面這篇文章主要給大家介紹了關(guān)于Android?app啟動(dòng)節(jié)點(diǎn)與上報(bào)啟動(dòng)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04Android實(shí)現(xiàn)顯示系統(tǒng)實(shí)時(shí)時(shí)間
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)顯示系統(tǒng)實(shí)時(shí)時(shí)間,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05