前面的章節有提到過,在 Dart 中,函數也是一個對象,它的類型是 Function。github
它能夠被賦值給變量,能夠被做爲參數傳遞。bash
這是個常規的函數聲明:閉包
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。post
fun(){}
assert(fun() == null)
複製代碼
若是一個函數只有一句表達式,能夠使用簡寫:ui
bool isNoble(int atomicNumber) => atomicNumber != null;
isNoble(int atomicNumber) => atomicNumber != null;
複製代碼
經過 {}
符號,能夠用於指定函數參數的名稱。atom
void enableFlags({bool bold = false, bool hidden = false, @required String content}) {
// ...
}
複製代碼
能夠看到,Dart 支持咱們給參數設置默認值。spa
調用:3d
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');
複製代碼
其中參數 device
和 mood
的位置的參數就是可選的,且 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);
}
複製代碼
從這個例子中,能夠感覺到閉包的強大,它至關於定義了一個動態可配置的函數對象。
Dart 提供了 typedef
關鍵字來定義一種函數格式(具備嚴格的格式檢查),好比:
typedef int Compare(Object a, Object b);
複製代碼
那麼,這種格式的函數就被定義成了 Compare 類型。實際上和類的定義是相似的概念。
看看這個例子:
Compare test = (Object a, Object b){
return 0;
}
複製代碼
形如此類的函數,就是 Compare 類型的函數。
當你打算把一個函數賦值給 Compare 類型的變量時,它會嚴格檢查 函數的參數類型 和 返回值類型 是否和 Compare 類型函數 徹底對應,不對應的話,編譯就會報錯。