1. 程式人生 > >Kotlin入門筆記三:可空型別

Kotlin入門筆記三:可空型別

這次文章給大家介紹下Kotlin中的可空型別,說起可空這個問題,那就不得不提空指標異常啦,大家在開發中肯定被空指標折磨的不要不要的。筆者在實習期間可是被空指標困擾了很長時間,動不動APP就Crash掉了,開啟Log一看,java.lang.NullPointerException就出現在眼前,接著就開始了漫長的非空判斷。

但是在kotlin中,這種現象得到了很好的控制,kotlin引入了可空型別,給開發者帶來了完美的解決方案,下面就來學習學習一下kotlin中可空型別。

1.可空型別的變數

kotlin中可以直接將一個變數宣告為可空型別,允許它為空,並且加入了很多的運算子,我們來一一學習:

首先我們來看看java中常規的判斷一個字串是否為空的寫法:

public class MyNull {
    public static void main(String[] args) {
        checkStringNull("");
    }

    private static String checkStringNull(String string) {
        return string == null ? "null" : string;
    }
}
// 輸出:null

再來對比下kotlin對可空變數的處理

fun main(args: Array<
String>) { var string: String? string = null; println(checkStringNull(string)) } fun checkStringNull(string: String?): String? { return string } // 輸出:null

這裡我們首先看到函式傳了一個String型別的引數,並且String後面多了一個,這就是kotlin的可空型別的宣告,它無需再像java那樣判斷是否為空,kotlin這種是允許為空,在宣告過後,這個變數就預設儲存了一個null引用,如果這個變數為空的話,就會取出這個null

引用。如果沒有修飾的變數是預設不可為空的。

2.安全呼叫運算子:"?:"

上面我們知道了如何宣告一個可空型別的變數,接著我們來看看如何運用這個可空變數:

我們通過一個例子來欣賞下安全呼叫運算子的強大之處:java版和kotlin版的小寫轉大寫

java:

public class MyNull {
    public static void main(String[] args) {
        String string = null;
        stringToUpperCase(string);
    }

    private static String stringToUpperCase(String string) {
        return string.toUpperCase();
    }
}
輸出結果
// AAA
// Exception in thread "main" java.lang.NullPointerException
// at MyNull.stringToUpperCase(MyNull.java:10)
// at MyNull.main(MyNull.java:6)

很明顯,在stringToUpperCase方法中沒有對string進行非空判斷,導致NullPointerException的異常丟擲。

kotlin:

fun main(args: Array<String>) {
    val string: String? = "aaa"
    val nullString: String? = null
    println(stringToUpperCase(string))
    println(stringToUpperCase(nullString))
}

fun stringToUpperCase(string: String?): String? {
    return string?.toUpperCase()
}
輸出結果:
// AAA
// null

kotlin卻沒有丟擲異常,而是返回了null,是不是很驚訝kotlin的強大,讓我們來看看kotlin的安全運算子是如何處理的:

安全運算子只會呼叫非空值的方法

只有當String不為空時,才會呼叫toUpperCase方法,String為空的時候,直接返回了null,這下媽媽再也不怕我們忘記處理空指標的情況了,哈哈~~

3.Elvis運算子:"?:"

在日常開發中我們也許會遇到這麼一個需求:如果介面返回的資料為空,顯示為“–”。這就得對資料為空的情況額外處理了,我們還是對比java和kotlin的做法:

java

public class MyNull {
    public static void main(String[] args) {
        String string = "aaa";
        String nullString = null;
        System.out.println(checkStringNull(string));
        System.out.println(checkStringNull(nullString));
    }

    private static String checkStringNull(String string) {
        return string == null ? "--" : string;
    }
}

輸出結果:
// aaa
// --

java中我們可以使用三元運算子來判斷是否為空,然後處理,這算是比較簡潔的寫法了,再來看看kotlin是否更簡單。

kotlin

fun main(args: Array<String>) {
    val string: String? = "aaa"
    val nullString: String? = null
    println(checkStringNull(string))
    println(checkStringNull(nullString))
}

fun checkStringNull(string: String?): String? {
    return string ?: "--"
}
輸出結果:
// aaa
// --

對比之下,kotlin程式碼貌似更簡單了呢,同時也出現了新的運算子,它就是:"?:" Elvis運算子,用來替代null這種預設值的情況。

Elvis運算子用bar來代替null

結合著這張圖,我們來看看**"?:"**是如何處理的,bar是用來代替預設值null的,如果foo==null,那麼就直接返回bar,和java中string == null ? "--" : string;三元運算子作用類似。

4.非空斷言:"!!"

kotlin還提供了一個運算子,如果你確定你的變數不可能為空,那麼就可以使用**!!**來修飾你的變數,這種情況下,如果你的變量出現了null的情況,就會丟擲空指標異常,我們來通過程式碼感受下:

fun main(args: Array<String>) {
    val string: String? = "aaa"
    val nullString: String? = null
    println(sureNotNull(string))
    println(sureNotNull(nullString))
}

fun sureNotNull(string: String?): String? {
    return string!!
}
輸出結果:
// Exception in thread "main" aaa
// kotlin.KotlinNullPointerException
//	at MyNullKt.sureNotNull(MyNull.kt:9)
//	at MyNullKt.main(MyNull.kt:5)

非空斷言要謹慎使用哦,別斷著斷著你的程式就crash掉了…

這期就給大家帶來這麼多,看完是不是覺得kotlin對開發者友好很多,有了可空型別的變數,我們就不必對介面返回的資料一一就行非空判斷了。下期筆者將為大家介紹下kotlin中的集合。

寫在最後

每個人不是天生就強大,你若不努力,如何證明自己,加油!

Thank You!

–Taonce