函數(shù)
1槽畔、Dart 是完全面向?qū)ο蟮恼Z言,即使是函數(shù)也是對象鞍爱,所以函數(shù)也可以被聲明成變量鹃觉,或者作為另一個函數(shù)的參數(shù)。也可以像調(diào)用函數(shù)一樣調(diào)用類的實例變量睹逃。
函數(shù)例子:
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
2盗扇、建議函數(shù)都指明返回值類型祷肯,雖然不寫類型也能執(zhí)行。
3疗隶、函數(shù)只有一行表達式的佑笋,可以使用尖頭語法簡寫成:
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
4、函數(shù)有兩種參數(shù)類型:規(guī)定參數(shù)和可選參數(shù)斑鼻。先列出規(guī)定參數(shù)蒋纬,可選參數(shù)跟隨其后。命名成可選的參數(shù)也可以被標(biāo)記為規(guī)定參數(shù)坚弱。
可選參數(shù)
可選參數(shù)可以按位置設(shè)置颠锉,或者按命名設(shè)置,但是不能同時使用史汗。
可選命名參數(shù)
調(diào)用一個函數(shù)時可以用參數(shù)名字指明參數(shù)使用paramName: value
.例如:
enableFlags(bold: true, hidden: false);
定義函數(shù)的時候使用{param1, param2, …}
來明確參數(shù):
void enableFlags({bool bold, bool hidden}) {...}
Flutter創(chuàng)建實例的表達式可以非常復(fù)雜琼掠,所以widget的構(gòu)造方法必須使用帶名稱的參數(shù)。這樣創(chuàng)建實例的表達式易于閱讀停撞。你也可以在任何Dart代碼中用@required標(biāo)記一個已經(jīng)命名的參數(shù)瓷蛙,來指明這是一個必選參數(shù)。例如:
const Scrollbar({Key key, @required Widget child})
當(dāng)一個Scrollbar被創(chuàng)建的時候戈毒,如果缺少參數(shù)艰猬,解析器會報錯。
可選位置參數(shù)
在函數(shù)參數(shù)中用[]符號包裹可選的位置參數(shù):
String say(String from, String msg, [String device] ) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
不帶可選參數(shù)調(diào)用方法舉例:
assert(say('Bob', 'Howdy') == 'Bob says Howdy');
包含可選參數(shù)舉例:
assert(say('Bob', 'Howdy', 'smoke signal') == 'Bob says Howdy with a smoke signal');
默認參數(shù)值
可以使用=來指明參數(shù)的默認值埋市。默認值必須是編譯時常量冠桃。如果沒有默認值,默認值就是null道宅。
有名參數(shù)的例子:
void enableFlags({bool bold = false, bool hidden = false}) {...}
enableFlags(bold:true);
位置參數(shù)的例子:
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');
也可以傳數(shù)組或者字典作為默認值食听,例如:
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');
}
main()函數(shù)
每個app必須有一個頂級的main()函數(shù),提供程序的入口污茵。main()函數(shù)返回void類型并且有一個list<String>類型的可選參數(shù)樱报。例子:
void main() {
querySelector('#sample_text_id')
..text = 'Click me!'
..onClick.listen(reverseText);
}
..語法叫級連。使用級連可以對一個對象的成員執(zhí)行多個操作泞当。
示例代碼:
void main(List<String> arguments) {
print(arguments);
assert(arguments.length == 2);
assert(int.parse(arguments[0]) == 1);
assert(arguments[1] == 'test');
}
函數(shù)作為一等對象
你可以傳遞一個函數(shù)作為另一個函數(shù)的參數(shù)迹蛤。例如:
void printElement(int element) {
print(element);
}
var list = [1.2.3];
list.forEach(printElement);
也可以聲明一個函數(shù)給一個變量,例如:
var loudify = (msg)
匿名函數(shù)
Dart也可以創(chuàng)建匿名函數(shù)襟士,或者叫作拉姆達表達式或閉包盗飒。可以給一個變量賦值一個匿名函數(shù)陋桂,例如在一個集合中進行添加逆趣、刪除。
匿名函數(shù)看起來像一個有名稱的函數(shù)零個或多個參數(shù)在圓括號中用逗號或中括號分隔章喉,代碼塊在函數(shù)體后邊汗贫。
下面的例子定義了一個匿名函數(shù)身坐,包含一個無類型的參數(shù)item。這個函數(shù)調(diào)用列表中的每一項落包,打印一個特定索引和其對應(yīng)值的字符串部蛇。
var list = ['apple', 'banana', 'orange'];
list.forEach((item) {
print('${list.indexOf(item)}:$item');
});
簡寫成
list.forEach((item) => print('${list.indexOf(item)}:$item'));
靜態(tài)作用域
Dart是一個靜態(tài)作用域的語言,意味著變量的作用域是在寫代碼的時候就提前定義好的咐蝇⊙穆常可以看一個函數(shù)是否在花括號里邊來看他的作用域。
下面是一個例子展示函數(shù)的嵌套和變量的作用域級別:
bool topLevel = true;
void main() {
var insideMain = true;
void myFunction() {
var insideNestedFunction = true;
assert(topLevel);
assert(insideMain);
assert(insideFunction);
assert(insideNestedFunction);
}
}
詞法閉包
一個閉包是一個函數(shù)對象有序,它有接口來獲取閉包中的變量抹腿,即使在它原來的作用域之外使用。
函數(shù)能夠關(guān)閉作用域內(nèi)的變量旭寿。下面的例子中makeAdder函數(shù)捕獲了addBy變量警绩。不管返回的參數(shù)在哪兒執(zhí)行,它都能記住addBy盅称。
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
檢測函數(shù)相等
下面的例子是測試頂級函數(shù)肩祥,靜態(tài)方法,和實例方法的相等:
void foo() {} // A top-level function
class A {
static void bar() {} // A static method
void baz() {} // An instance method
}
void main() {
var x;
// Comparing top-level functions.
x = foo;
assert(foo == x);
// Comparing static methods.
x = A.bar;
assert(A.bar == x);
// Comparing instance methods.
var v = A(); // Instance #1 of A
var w = A(); // Instance #2 of A
var y = w;
x = w.baz;
// These closures refer to the same instance (#2),
// so they're equal.
assert(y.baz == x);
// These closures refer to different instances,
// so they're unequal.
assert(v.baz != w.baz);
}
返回值
所有的函數(shù)都有返回值缩膝,如果沒有指明返回值混狠,函數(shù)返回null;會默認的拼接到函數(shù)體疾层。
foo() {}
assert(foo() == null);