【修煉內功】[kotlin] 聊一聊泛型的可空性

本文已收錄 【修煉內功】躍遷之路

什麼?泛型自己也能夠是nullable?上來就拋這麼個問題實在是不夠友好~html

首先回顧,什麼是泛型?Oracle Java Tutorialsjava

Introduced in J2SE 5.0, this long-awaited enhancement to the type system allows a type or method to operate on objects of various types while providing compile-time type safety. It adds compile-time type safety to the Collections Framework and eliminates the drudgery of casting.

泛型的本質是參數化類型,也就是說操做的數據類型被指定爲一個參數。簡單來說,泛型就是操做類型的佔位符。shell

那,爲何要使用泛型?Oracle Java Tutorialssegmentfault

In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types.

泛型的好處是在編譯的時候作類型安全檢查,而且全部的強制轉換都是自動和隱式的,提升代碼的重用率。安全

在深刻討論泛型的可空性以前,首先看一個簡單的例子 (kotlin中更多泛型的介紹,以及其與java泛型的區別,能夠查看Generics)oracle

fun <T> whoAmI(t: T) {
    val clazz = t::class
    println("I'm $clazz")
}

上面的代碼是編譯不過的,問題在於
clipboard.pngide

nullable type 'T'是什麼鬼?OK,咱們按照提示,爲參數t加上!!強制標識爲not-null (關於!!的使用,能夠查看Null Safety)函數

clipboard.png

WTF~ 嗶~ 卒~this

在繼續討論以前,先關注兩個概念,type parametertype argument,在一個函數中,前者是函數參數的類型(類型),如translate(java.lang.String, java.lang.String)中的java.lang.String,然後者則是函數調用時傳入的具體值(類型),如translate("Hello You!", "zh-cn")中的Hello Youzh-cn,泛型做爲一個佔位符,佔的正是type parameter的位spa

首先簡單瞭解一下argument的可空性,kotlin中控制函數參數值(類屬性值等)的nullable是經過?符號實現的,默認均爲non-nullable,如如下代碼片斷是編譯不過的

clipboard.png

只有指定參數name爲nullable,才能夠順利編譯

clipboard.png

一樣,對應泛型類,咱們也能夠指定nullable及non-nullable的type argument

clipboard.png

從上例中能夠看到, null在kotlin中的類型爲 Nothing?(kotlin中一切皆爲對象)

更多內容請參考 Null Safety

說了這麼多,到底什麼是泛型的可空性(type argumentnullable)?

上例中,之因此能夠將forestA指定爲Forest<Tree?>,是由於,每個nullabletype argument都有一個隱式邊界Any?,即以下兩種類聲明徹底等價

// T的隱式邊界爲Any?
class Forest<T>

// 顯示指定T的邊界爲Any?
class Forest<T : Any?>

// 顯示指定T的邊界爲Tree?
class Forest<T : Tree?>

若是將Forest中的泛型強制指定爲non-nullable會發生什麼

clipboard.png

什麼?不能將nullable的Tree?應用到Forest類了!這是由於Forest類的定義中,咱們強制將泛型的邊界指定爲了non-nullable的Tree

因此,回到文章的開頭,函數whoAmI的錯誤信息nullable type 'T'指的是哪一個鬼?泛型T的默認邊界爲Any?,即T : Any?,因此,咱們只須要顯示指定T爲non-nullable便可

clipboard.png

至此,對於nullablenon-nullabletype parametertype argument是否有所瞭解?


訂閱號

相關文章
相關標籤/搜索