目錄
一、Dart方法
Dart是一種真正的面嚮對象語言,所以即使函數也是對象,具有類型和功能,意味着函數可以分配給變量或作爲參數傳遞給其他函數
String greet(String name) {
return 'Hello, $name';
}
- 對於公開的API,推薦使用靜態類型,不過這不代表靜態類型是強制的,也可以不使用靜態類型,而使用自動類型推斷
greet(name) {
return 'Hello, $name';
}
1. 箭頭語法
對於只包含一個表達式,可以簡寫爲:
bool greaterThanTen(n) => n > 10;
// 它相當於:
bool greaterThanTen(n) {
return n > 10;
}
也就是說,·縮寫的語法=> expr相當於{ return expr; }·
說明
在箭頭(=>)和分號(;)之間只能出現一個表達式,不能使用語句(if、else、while之類),但是可以使用表達式與條件表達式
2、必選參數與可選參數
可選的命名參數
在定義函數時,使用{param1, param2,…}來指定命名參數:
void greet({ String action, String what }) {
print('$action $what');
}
在調用函數時,可以使用paramName: value來指定命名參數
// 調用方法如下:
greet(what: 'Hello', action: 'say');
可選參數
可選參數需要將放置於[]中,如下:
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
// 調用方法如下:
say('Ruphi', 'hello'); // 輸出: Ruphi says Hello
say('Ruphi', 'hello', 'iPhone 8 Plus');
/*
輸出:
Ruphi says Hello
via iPhone 8 Plus
*/
默認參數
可以使用 = 來定義命名和位置參數的默認值。默認值必須是編譯時常量。如果沒有提供默認值,則默認值爲null。
void defaultArgs({ String from = 'Lili', String msg = 'Hello' }){
print('$from says $msg');// 輸出:Lili says Hello
}
3. main() 函數
每個應用程序都必須有一個頂級的main()函數,它作爲應用程序的入口。main()函數返回void,並有一個可選的List參數作爲參數。
void main(List<String> args){
print(args); //輸出:[]
}
4. 一等方法對象
- 可以將函數作爲參數傳遞給另一個函數
void printElement(int element) {
print(element);
}
void funAsArgs(){
var list = [1, 2, 3];
// 將函數作爲變量傳入
list.forEach(printElement);
}
- 也可以賦值給一個變量
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');
5.匿名函數(lambda函數或者閉包函數)
匿名函數:沒有函數名稱的函數
匿名方法的語法如下:
([[Type] param1[, ...]]) {
codeBlock;
};
···
可以爲變量分配一個匿名函數
```java
var list = ['apples', 'bananas', 'oranges'];
/*list.forEach((item) {
print('${list.indexOf(item)}: $item');
});*/
// 如果函數只包含一條語句,可以使用胖箭頭符號來縮短它
// 等效於
list.forEach(
(item) => print('${list.indexOf(item)}: $item')
);
6.詞法作用域(靜態作用域)
Dart變量的作用域在寫代碼的時候就已經確定了,因此,大括號裏定義的變量就只能在大括號裏訪問
bool topLevel = true;
void grammerScope(){
var insideMain = true;
void myFunction() {
var insideFunction = true;
void nestedFunction() {
var insideNestedFunction = true;
assert(topLevel);
assert(insideMain);
assert(insideFunction);
assert(insideNestedFunction);
}
}
}
7.詞法閉包
一個閉包是一個方法對象,不論該對象在何處被調用,該對象都能訪問自己作用域內的變量(即捕獲了的變量),如下:
Function uid() {
int id = 0;
return () => id++;
}
void lexicalClosure() {
var uidGenerator = uid();
print(uidGenerator());
print(uidGenerator());
print(uidGenerator());
/**輸出
* 0
1
2
*/
}
8.判斷函數相等
foo() {} // 頂級函數
class A {
static void bar() {} // 靜態方法
void baz() {} // 實例方法
}
main() {
var x;
// 比較頂級方法
x = foo;
assert(foo == x); // 通過
// 比較靜態方法
x = A.bar;
assert(A.bar == x); // 通過
// 比較實例方法
var v = new A(); // A的實例 #1
var w = new A(); // A的實例 #2
var y = w;
x = w.baz;
// 因爲 y.baz 和 x 都是指向實例#2的baz方法,因此它們是相等的
assert(y.baz == x); // 通過
// v.baz指向的是#1的baz方法,w.baz指向的是#2的baz方法,因此它們不相等
assert(v.baz != w.baz); // 通過
}
9.返回值
所有函數都返回一個值。如果沒有指定返回值,則語句返回null;隱式附加到函數體。