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

Kotlin中空判斷處理操作實(shí)例

 更新時(shí)間:2022年07月29日 09:20:22   作者:android_cai_niao  
最近使用kotlin重構(gòu)項(xiàng)目,遇到了一個(gè)小問題,在Java中,可能會遇到判斷某個(gè)對象是否為空,為空執(zhí)行一段邏輯,不為空執(zhí)行另外一段邏輯,下面這篇文章主要給大家介紹了關(guān)于Kotlin中空判斷處理操作的相關(guān)資料,需要的朋友可以參考下

Kotlin中的一個(gè)偉大創(chuàng)前舉就是空指針的處理,在代碼的編譯階段就能檢測可能出現(xiàn)的空指針問題,示例代碼如下:

data class Person(var name: String? = null)

fun sayHello(name: String) {
    println("Hello $name")
}

fun main() {
    val person = Person("Even")
    if (person.name != null) {
        sayHello(person.name)
    }
}

在IntelliJ中,如上代碼會報(bào)錯,如下:

提示的錯誤信息翻譯為:智能強(qiáng)制轉(zhuǎn)換為’String’是不可能的,因?yàn)?rsquo;person.name’是一個(gè)可變屬性,此時(shí)可能已經(jīng)被更改了。

要想編譯通過,需要這樣做:

sayHello(person.name!!)

哎?我記得學(xué)Kotlin的時(shí)候有解釋說如果已經(jīng)判斷了不是空了的話,就不需要添加 !! 符號的,為什么這里不添加的話會報(bào)錯呢?其實(shí)原因就是報(bào)錯信息上提示的,因?yàn)閚ame是用var修飾的,而且這是一個(gè)成員變量,雖然你做了非空的判斷,但是判斷之后,這個(gè)成員屬性有可能在其它線程被修改了,比如在其他線程設(shè)置為null了,所以,這樣的話就會出現(xiàn)空指針異常了,所以添加 !! 符號來解決報(bào)錯不是最佳實(shí)踐,在我這個(gè)示例中,我們知道沒有開多線程去修改person的name屬性,所以可以加 !! 來解決,但是最好不要這樣做,如果我們知道name屬性不會被修改,則可以使用val修飾,如下:

可以看到,此時(shí)不需要添加 !! 也不報(bào)錯了,因?yàn)镮DE知道name是一個(gè)不可變屬性,判斷了不是空之后,就永遠(yuǎn)不可能是空了。

有時(shí)候,name屬性就需要發(fā)生變化,就必須聲明為var,此時(shí)怎么解決呢?,可以通過添加局部變量解決,如下:

如上代碼,IDE沒有報(bào)錯。我們通過添加一個(gè)val類型的name局部變量來保存person.name的值,這樣的話,判斷了name為不為空之后,即使person.name在子線程被設(shè)置為空了,但是局部變量name不會受到影響。我們在閱讀一些系統(tǒng)源碼的時(shí)候,不論是Java源碼或是Kotlin的源碼,經(jīng)常發(fā)現(xiàn)別人在判斷一個(gè)對象的屬性的可空性的時(shí)候,都是先聲明一個(gè)局部變量保存該對象屬性再來判斷,不懂事的時(shí)候就會奇怪別人為什么要多此一舉,現(xiàn)在明白了,別人是為了預(yù)防直接判斷對象屬性出現(xiàn)的多線程修改帶來的問題。

添加局部變量的話,即使是var類型的局部變量IDE也能判斷是否為空,示例如下:

如上代碼,可以看到,局部變量name是可變類型的,但是也不需要添加 !! 符號,因?yàn)関ar類型的局部變量不會被子線程修改,所以判斷了不為空之后就不會為空。最后賦值了”Lily“,然后傳給sayHello(name),這里并沒有做非空判斷啊,sayHello接受的是不可空的String,但是name是一個(gè)可空String啊,道理也很簡單,因?yàn)檫@是局部變量,沒有子線程的干擾,IDE能檢測到name在傳給sayHello之前是賦值了”Lily"的,之后沒有再賦值為null也是能檢測出來的,所以這里不需要做可空判斷也能編譯通過。如果沒有賦值“Lily",則IDE就不知道name是否為空了,就會報(bào)錯,如下:

或者,如果我們使用的是一個(gè)成員變量,即使前一句代碼賦值了下一句就用也是會報(bào)錯的,原因就是它有可能在子線程被設(shè)置為null了,如下:

所以,Kotlin是真的很強(qiáng),如果你在使用一個(gè)變量,只要IDE沒報(bào)錯,你就可以放心的使用,不需要做空判斷,你可以放心,運(yùn)行時(shí)不會有空指針問題的。如果IDE報(bào)錯了,就是有可能發(fā)生空指針的,此時(shí)你就不要強(qiáng)制添加 !! 來逃避問題了,一定要做合理的空指針判斷處理。如果你使用Java的話,要不要做空指針處理IDE是沒有提示的,你只能自己用腦子去想要不要做空指針判斷處理,事實(shí)往往是我們根本就不去想要不要做處理,或者即使思考過了,也會有思考出錯的時(shí)候,比如可能出現(xiàn)空指針的地方,但是你寫代碼時(shí)你認(rèn)為不會出現(xiàn)空指針,所以你沒做非空判斷處理,則運(yùn)行時(shí)就有可能出現(xiàn)空指針異常了。而Kotlin就會有提示,只要IDE沒報(bào)錯就不用做空指針處理,只要IDE報(bào)錯了就要做空指針處理,這真是爽歪歪啊,你不需要去思考什么時(shí)候應(yīng)該添加空指針判斷處理了!

注:這個(gè)可空判斷也適用于類型智能轉(zhuǎn)換,這個(gè)知識點(diǎn)在官網(wǎng)教程上也找到了答案:https://kotlinlang.org/docs/typecasts.html#unsafe-cast-operator,相關(guān)內(nèi)容如下:

Note that smart casts work only when the compiler can guarantee that the variable won’t change between the check and the usage. More specifically, smart casts can be used under the following conditions:

val local variables - always, with the exception of local delegated properties.

val properties - if the property is private or internal or if the check is performed in the same module where the property is declared. Smart casts cannot be used on open properties or properties that have custom getters.

var local variables - if the variable is not modified between the check and the usage, is not captured in a lambda that modifies it, and is not a local delegated property.

var properties - never, because the variable can be modified at any time by other code.

附:?.和!!.

其實(shí)kotlin是非常人性話的,你定義了一個(gè)可為空的變量但是你依然可以去操作的。我們修改一下上面的寫法:

val a:String = "我加小明"
val b:String ?= null
val c:String? = "我加小明"

? println(a.length)
? println(b?.length)
? ?println(c!!.length)

這樣編譯就通過。

這里的**?.**就是相當(dāng)于Java的如果為空就返回null 而kotlin強(qiáng)制讓我們?nèi)ヌ幚恚@樣就避免了很多空指針異常

if(b==null) return null;

當(dāng)然如果你不想直接為null,你說當(dāng)為空時(shí)我想自己去處理,kotlin還有語法**?:**

val b:String ?= null
 println(b?.length?:"我錯了")

!!. 表示我任性,告訴編譯器不要去做非空檢查,為空就拋異常

總結(jié)

到此這篇關(guān)于Kotlin中空判斷處理操作的文章就介紹到這了,更多相關(guān)Kotlin空判斷處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論