《Kotlin實(shí)戰(zhàn)》- 6 Kotlin 的類型系統(tǒng)

6.1 可空性

kotlin 中加入了可空類型的概念,編譯器強(qiáng)制把類型分為可空的和非空的,可空類型通過在類型后加上 ? 號來表示。

當(dāng)一個類型被聲明為非空時,如下

funstrLen(s:String)=s.length

這個函數(shù)中的參數(shù)被聲明成 String 類型,在 Kotlin 中這表示它必須包含一個 String 實(shí)例。 這一點(diǎn)由編譯器強(qiáng)制實(shí)施,如果傳 null,在編譯器就會報錯。這樣就保證了 strLen 函數(shù)永遠(yuǎn)不會在運(yùn)行時拋出 NullPointerException。

可空類型并不是非空類型的包裝,所有檢查都發(fā)生在編譯器,這意味著 kotlin 的可空類型并不會在運(yùn)行時帶來額外開銷。

基于此,kotlin 引入了一些安全訪問可空值得特殊運(yùn)算符來使用可空類型

安全調(diào)用運(yùn)算符:?. (如果作用在 null 上,本次調(diào)用不會執(zhí)行,且整個表達(dá)式返回 null)

Elvis 運(yùn)算符:?:

安全轉(zhuǎn)換:as? (如果值不是合適的類型就返回 null)

非空斷言:!!

let 函數(shù):? 用法:?.let {}

延遲初始化屬性:lateinit

Kotiin 通常要求你在構(gòu)造方法中初始化所有屬性,如果某個屬性是非空類型,你就必須提供非空的初始化值。否則,你就必須使用可空類型。如果你這樣做,該屬性的每一次訪問都需要 null 檢查或者 ! !運(yùn)算符。

使用 lateinit 可以定義延遲初始化屬性,注意,延遲初始化的屬性都是 var,因?yàn)樾枰跇?gòu)造方法外修改它的值,而 val 屬性會被編譯成必須在構(gòu)造方法中初始化的 final 字段 。

privatelateinitvarmyService:MyService

Kotlin 為可空類型定義了方便使用的擴(kuò)展函數(shù),可以允許接收者為 null 的調(diào)用,如 isEmpty、isBlank、isEmptyOrNull、isNullOrBlank 就可以由 String ? 類型的接收者調(diào)用。

6.1.10 類型參數(shù)的可空性

...

6.3 集合與數(shù)組

注意 List<Int?> 與 List<Int>? 的區(qū)別

如果過濾掉 List<Int?> 中所有 null 值,只保留非 null 值,可以使用系統(tǒng)提供的 filterNotNull 方法。過濾后類型變?yōu)?List<Int>

Kotlin 把對集合的讀、寫接口分開,kotlin.collections.Collection 接口對集合是可讀不可寫的,kotlin.collections.MutableCollection 繼承自 Collection 提供了添加和移除的方法,是可讀寫的。這樣會讓程序中數(shù)據(jù)發(fā)生的事情更容易理解,如果一個方法接收 Collection 而不是 MutableCollection,就知道它是不會修改集合的。

每一種 Java 集合接口在 Kotlin 中都有兩種表示,一種是只讀的,另一種是可變的。

一般規(guī)則是都優(yōu)先使用只讀接口,當(dāng)需要修改集合時再使用可變接口。

因?yàn)?java 中沒有不可變集合,所有當(dāng) kotlin 調(diào)用 java 的方法并傳入一個不可變集合時,java 可以修改集合而破壞不可變性,所以你有責(zé)任使用正確的參數(shù)類型。同樣也適用于包含非空類型元素的集合。

優(yōu)先使用集合而不是數(shù)組;

kotlin 中創(chuàng)建數(shù)組的幾種方式:

arrayof ,可帶參數(shù)來初始化數(shù)組的值

arrayOfNulls:創(chuàng)建一個給定大小的數(shù)組,包含的是 null 元素,顯然它只能用來創(chuàng)建包含元素類型可空的數(shù)組

Array:構(gòu)造方法接收數(shù)組的大小和一個 lambda 表達(dá)式,調(diào)用 lambda 表達(dá)式來創(chuàng)建每一個數(shù)組元素;其中 lambda 接收數(shù)組元素下標(biāo)并返回放在數(shù)組下標(biāo)位置的值。

使用 toTypeArray 可以將 List 轉(zhuǎn)為數(shù)組,另外,kotlin 提供了若干獨(dú)立的類:IntArray、ByteArray等,每一種基本類型都對應(yīng)一個。

類似的,可以使用 IntArray(5)、intArray(0,0,0,0,0)、IntArray(5){ i ->? (i+1) * (i+1)} 進(jìn)行初始化,或者調(diào)用 List 的 toIntArray 方法轉(zhuǎn)成數(shù)組。

kotlin 支持和集合相同的用于數(shù)組的擴(kuò)展函數(shù),比如 filter、map 等。

6.4 小結(jié)

Kotlin 對可空類型的支持,可以幫助我們在編譯期檢測出潛在的 NullPointerException 錯誤。

Kotlin 提供了像安全調(diào)用(?.)、 Elvis 運(yùn)算符(?:)、非 空 斷 言(!!)及 let 函數(shù)這樣的工具來簡潔地處理可空類型。

as?運(yùn)算符提供了一種簡單的方式來把值轉(zhuǎn)換成一個類型,以及處理當(dāng)它擁有不同類型時的情況。

Java 中的類型在 Kotlin 中被解釋成平臺類型,允許開發(fā)者把它們當(dāng)作可空或非空來對待。

表示基本數(shù)字的類型(如 Int)看起來用起來都像普通的類,但通常會被編譯成 Java 基本數(shù)據(jù)類型。

可空的基本數(shù)據(jù)類型(如 Int?)對應(yīng)著 Java 中的裝箱基本數(shù)據(jù)類型(如 java.lang.Integer )。

Any 類型是所有其他類型的超類型,類似于 Java 的 Object。而 Unit 類比于 void。

不會正常終止的函數(shù)使用 Nothing 類型作為返回類型。

Kotlin 使用標(biāo)準(zhǔn) Java 集合類,并通過區(qū)分只讀和可變集合來增強(qiáng)它們。

當(dāng)你在 Kotlin 中繼承 Java 類或者實(shí)現(xiàn) Java 接口時,你需要仔細(xì)考慮參數(shù)的可空性和可變性。

Kotlin 的 Array 類就像普通的泛型類 ,但它會被編譯成 Java數(shù)組 。

基本數(shù)據(jù)類型的數(shù)組使用像 IntArray 這樣的特殊類來表示 。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容