dart系列之:和null說再見,null使用最佳實踐

簡介

null可能是大家在編寫程式中最為頭疼的一個東西,稍不留意的情況下就有可能使用到了這個空字元。所以dart在2.12引入了nll safety,默認情況下強制所有的類型都不為null,只有在你認為它可以為null的時候才可以設置為null。

雖然有了null safety,但是這裡還有一些我們需要考慮的null的最佳實踐。

不需要初始化對象為null

在dart2.12之後,所有的對象都強製為非空的,除非你顯示指定其為可空的對象。

如果一個對象可以為空,那麼我們可以這樣指定:

String? name;

如果定義一個對象可以為空,那麼對dart來說會隱式對其初始化為null。

所以下面的顯示初始化為null是完全沒有必要的:

String? name=null;

同樣的,如果參數是一個可以為空的對象,那麼dart也會將其初始化為null,我們也沒有必要顯示去設置其值:

void echoName(String? name){
    print(name);
}

null的三元操作符

所謂三元就是有三個變數,我們常見的三元操作符就是?:,通常來說是這樣用的:

name==null?true:false;

上面的邏輯實際上是把一個null轉換成了一個bool類型。

為了實現這個功能,dart提供了一個更加簡潔的操作符??, 可以這樣使用:

name??false;

上面的程式碼表示如果name是空,則返回false。

注意,這裡只是返回值改變了,但是name值本身並沒有變化,也不會將name從一個可為空的類型,變成不為空的類型。所以如果我們在if語句裡面對字元進行判斷,則還是需要顯示進行null的比較:

int measureMessage(String? message) {
  if (message != null && message.isNotEmpty) {
      // dart知道message不為空
    return message.length;
  }

  return 0;
}

如果這樣編寫,則會出現異常:

int measureMessage(String? message) {
  if (message?.isNotEmpty ?? false) {
    //dart並不知道message不為空
    return message!.length;
  }

  return 0;
}

如果在使用中需要判斷類型是否為空,則不要使用late

late是做什麼用的呢?late表示該類型目前不會初始化,但是會在未來的某個時間對其進行初始化。

所以,如果你用late表示某個類型,那麼在後續使用的時候是不需要進行手動判斷該類型是否為空的。

如果你仍然要手動判斷,那麼就沒必要設置該類型為late。

本地變數的類型提升

dart有一個非常好的特性,就是當我們判斷一個變數不為空之後,該變數就會被提升為非空變數。

當提升為非空變數之後,就可以自由訪問該非空變數內部的屬性和方法了。

但是可惜的是,dart中的類型提升只是針對與local變數或者參數而言的,對於類變數或者是top level的變數並不適用,所以我們需要將這些變數拷貝到本地變數,從而使用類型提升的特性。

我們看下面的例子:

class UploadException {
  final Response? response;

  UploadException([this.response]);

  @override
  String toString() {
    var response = this.response;
    if (response != null) {
      return 'Could not complete upload to ${response.url} '
          '(error code ${response.errorCode}): ${response.reason}.';
    }

    return 'Could not upload (no response).';
  }
}

其中UploadException中的response是一個頂級變數,雖然我們對其進行測試是否為空,但是在使用的過程中還是不能直接訪問其內部的屬性,因為response可能為空。

為了使用dart的類型提升的特性,我們可以將頂級的變數賦值給一個本地變數,從而在null測試之後,自動將其提升為非空的類型,從而直接訪問其內部的屬性。

總結

以上就是dart中null用法的最佳實踐。

本文已收錄於 //www.flydean.com/29-dart-null-effective/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!