一、可空類型系統(tǒng)
Kotlin默認(rèn)所有的參數(shù)和變量都不可為空。
Int 表示不可為空的整型
Int? 表示可為空的整型
eg:
fun doStudy(study: Study?) {
if (study != null) {
study.doHomeWork()
study.readBook()
}
}
有點啰嗦吧,別急,Kotlin還提供了一系列輔助工具幫我們作判空處理。
二、判空輔助工具
1. ?.操作符
表示當(dāng)對象不為空的時候正常調(diào)用相應(yīng)的方法,當(dāng)對象為空的時候什么都不做。
使用 ?.操作符改變上面代碼:
fun doStudy(study: Study?) {
study?.doHomeWork()
study?.readBook()
}
2. ?:操作符
這個操作符左右兩邊都接收一個表達式,如果左邊的表達式的結(jié)果不為空就返回左邊表達式的結(jié)果,否則就返回右邊表達式的結(jié)果。
//原代碼
var c = if (a != nul) a else b
//使用?:操作符
var c = a ?: b
3. !!操作符
Kotlin也不是特別的智能,有時候我們邏輯上已經(jīng)將空指針異常處理了,單Kotlin編譯器并不知道,那么這個時候還是會編譯失敗,比如以下例子:
var content: String? = "hello"
fun main() {
if (content != null) {
printUpperCase()
}
}
fun printUpperCase() {
val toUpperCase = content.toUpperCase()
print(toUpperCase)
}
這段代碼邏輯沒問題,但是一定無法執(zhí)行。因為printUpperCase()函數(shù)并不知道外部已經(jīng)對content做了非空檢查,所以在調(diào)用toUpperCase()時,還認(rèn)為存在空指針方風(fēng)險。
使用!!操作符:
fun printUpperCase() {
val toUpperCase = content!!.toUpperCase()
print(toUpperCase)
}
這是一個種有風(fēng)險的寫法,意在告訴Kotlin,我非常確信這里的對象不會是空,所以不用你來做非空檢查了,如果出現(xiàn)問題,可以直接拋出空指針異常,后果我自己承擔(dān)。
4. let函數(shù)
let既不是操作符也不是關(guān)鍵字,是一種函數(shù)。這個函數(shù)提供了函數(shù)式API的編程接口,并將原始調(diào)用對象作為參數(shù)傳遞到lambda表達式中,示例代碼:
obj.let { obj2 ->
//編寫具體的業(yè)務(wù)邏輯
}
obj與obj2是一個對象。
let函數(shù)配合?.操作符做空檢查:
fun doStudy(study: Study?) {
study?.let { stu ->
stu.readBook()
stu.doHomeWork()
}
}
這樣我們對study對象只做了一次非空判斷就可以使用了。
優(yōu)化之后:
fun doStudy(study: Study?) {
study?.let {
it.readBook()
it.doHomeWork()
}
}
另外,let函數(shù)是可以處理全局變量的判空問題的。而if無法做到這一點。