8.掌握了Dart中的函式,你就掌握了原力!

CoorChice發表於2019-03-19

目錄傳送門:《Flutter快速上手指南》先導篇

前面的章節有提到過,在 Dart 中,函式也是一個物件,它的型別是 Function

它可以被賦值給變數,可以被作為引數傳遞。

宣告一個函式

這是個常規的函式宣告:

bool isNoble(int atomicNumber) {
  return atomicNumber != null;
}
複製程式碼
  • 如果一個函式沒有顯示宣告返回值,Dart 會自動推導它的返回值型別。

    void main() {
    
      bool b = isNoble(2);
      print(b);
    }
    
    isNoble(int atomicNumber) {
      return atomicNumber != null;
    }
    
    
    >>>
    true
    複製程式碼
  • 如果一個函式沒有顯示的 return,那麼它預設會返回 null。

    fun(){}
    
    assert(fun() == null)
    複製程式碼
  • 如果一個函式只有一句表示式,可以使用簡寫:

    bool isNoble(int atomicNumber) => atomicNumber != null;
    
    isNoble(int atomicNumber) => atomicNumber != null;
    複製程式碼

可選命名引數

通過 {} 符號,可以用於指定函式引數的名稱。

void enableFlags({bool bold = false, bool hidden = false, @required String content}) {
    // ...
}
複製程式碼

可以看到,Dart 支援我們給引數設定預設值。

呼叫:

enableFlags(bold: true, content: 'required');
enableFlags(bold: true, hidden: false, content: 'required');
複製程式碼

使用 @required 註釋的引數,表示必要的引數,在呼叫的時候你不能遺漏它。

這樣的書寫形式也是被允許的,不使用 :

void doStuff(
    {List<int> list = const [1, 2, 3],
    Map<String, String> gifts = const {
      'first': 'paper',
      'second': 'cotton',
      'third': 'leather'
    }}) {
  print('list:  $list');
  print('gifts: $gifts');
}
複製程式碼

可選位置引數

通過 [] 符號,可以指定該位置的引數是可選的:

String say(String from, String msg,
    [String device = 'carrier pigeon', String mood]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  if (mood != null) {
    result = '$result (in a $mood mood)';
  }
  return result;
}

assert(say('Bob', 'Howdy') ==
    'Bob says Howdy with a carrier pigeon');
複製程式碼

其中引數 devicemood 的位置的引數就是可選的,且 device 有預設值。

函式作為變數

正如前面所說,Dart 中的函式是一個 Function 型別的物件,因此它可以被賦值給一個變數。

var say= (str){
  print(str);
};
say("hi world");
複製程式碼

函式作為入參

函式作為一個物件,它當然也可以被作為引數傳遞:

void execute(var callback){
    callback();
}
execute(()=>print("xxx"))
複製程式碼

函式閉包

Dart 函式的特性,使得它很容易實現閉包:

// 返回一個函式物件
Function makeAdder(num addBy) {
  return (num i) => addBy + i;
}

void main() {
  // 建立一個 +2 的函式
  var add2 = makeAdder(2);

  // 建立一個 +4 的函式
  var add4 = makeAdder(4);

  assert(add2(3) == 5);
  assert(add4(3) == 7);
}
複製程式碼

從這個例子中,可以感受到閉包的強大,它相當於定義了一個動態可配置的函式物件。

typedef 關鍵字

Dart 提供了 typedef 關鍵字來定義一種函式格式(具有嚴格的格式檢查),比如:

typedef int Compare(Object a, Object b);
複製程式碼

那麼,這種格式的函式就被定義成了 Compare 型別。實際上和類的定義是類似的概念。

看看這個例子:

Compare test = (Object a, Object b){
    return 0;
}
複製程式碼

形如此類的函式,就是 Compare 型別的函式。

當你打算把一個函式賦值給 Compare 型別的變數時,它會嚴格檢查 函式的引數型別返回值型別 是否和 Compare 型別函式 完全對應,不對應的話,編譯就會報錯。

目錄傳送門:《Flutter快速上手指南》先導篇

如何找到我?

傳送門:CoorChice 的主頁

傳送門:CoorChice 的 Github


相關文章