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

flydean發表於2022-01-17

簡介

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用法的最佳實踐。

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

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

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

相關文章