Dart語言是純面向對象的編程語言,就算是函數(對象的成員函數一般稱為方法)也是對象,它也有類型,那麼函數也可以作為其他函數的參數,或者賦值給其他變數。除此之外,Dart中的函數還有什麼特別之處、它有什麼規則和約束…… ...
Dart官方文檔:https://dart.dev/language/functions
重要說明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。
Dart語言是純面向對象的編程語言,就是是函數也是對象,它的類型就是Function
類(https://api.dart.dev/stable/3.1.3/dart-core/Function-class.html)。
如下代碼樣例,函數的不同實現。如果函數實現僅僅只有1個表達式,那麼函數可以使用箭頭語法:=> return expression;
// 函數實現
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
// 箭頭語法,上訴函數的簡單語法
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
命名參數(必選,預設值)
參數格式:functionName({param1 = value1, param2, ...})
函數調用:functionName(param1: valueX, param2: value2, ...)
預設情況下,命名參數是可選的,除非顯示增加required
標記。在Flutter中,尤其是Widget是構造函數,僅僅使用命名參數,儘管參數是必填參數。
特別註意:就算了增加required
的必選參數,它也可以是可空的。
位置參數(可選,預設值)
可選位置參數通過[]
包裹的參數列表,預設值為null
,可以設置預設值:
參數格式:functionName(param1, param2, [param3 = value3, param4]);
函數調用:functionName(value1, value2);或functionName(value1, value2, value3);或functionName(value1, value2, value3, value4);
main()函數
任何Dart應用,都必須包含一個頂級main()
函數,它是應用的唯一入口。它的返回值是void
,入參是List<String>
類型。
代碼樣例:如下代碼,我們在執行Dart文件時,指定了參數dart args.dart 1 test
void main(List<String> arguments) {
print(arguments);
assert(arguments.length == 2);
assert(int.parse(arguments[0]) == 1);
assert(arguments[1] == 'test');
}
函數作為參數
函數可以作為其他函數的入參,也可以賦值給變數。
// 1. 函數作為函數入參
void printElement(int element) {
print(element);
}
var list = [1, 2, 3];
list.forEach(printElement);
// 2. 函數賦值給變數(匿名函數)
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');
匿名函數
如上代碼,main()
和printElement()
函數都是命名函數。我們也可以創建匿名函數(如上代碼loudify
變數的值),特別是在Lambda表達式
或者在閉包函數
中,匿名函數使用場景很多。
代碼樣例:如下代碼,map()
和forEach()
的入參就是匿名函數。
void main() {
const list = ['apples', 'bananas', 'oranges'];
list
.map((item) => item.toUpperCase())
.forEach((item) => print('$item: ${item.length}'));
}
函數相等校驗
可以進行相等校驗的函數包括:頂級函數,靜態函數和實例函數。
// 1. 頂級函數
void foo() {}
class A {
// 2. 靜態方法
static void bar() {}
// 3. 實例方法
void baz() {}
}
void main() {
Function x;
// 頂級函數相等校驗
x = foo;
assert(foo == x);
// 靜態方法相等校驗
x = A.bar;
assert(A.bar == x);
// 實例方法相等校驗
var v = A(); // A實例#1
var w = A(); // A實例#2
var y = w;
x = w.baz;
// 同是A實例#2方法
assert(y.baz == x);
// 不同實例方法
assert(v.baz != w.baz);
}
函數返回值
如果沒有顯示返回值,函數預設返回null
,Record記錄可以聚合返回多個值。
(String, int) foo() {
return ('something', 42);
}
生成器函數
生成器函數可以延遲產出一系列值,Dart中內置2類生成器函數:
- 同步生成器:返回1個Iterable對象。
- 非同步生成器:返回1個Stream對象。
同步生成器函數:使用sync*
標記函數體,並且使用yield
表達式產生值。
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
非同步生成器函數:使用async*
標記函數體,並且使用yield
表達式產生值。
Stream<int> asynchronousNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
如果生成器是遞歸的,可以通過yield*
來提升性能。
Iterable<int> naturalsDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* naturalsDownFrom(n - 1);
}
}
我的本博客原地址:https://ntopic.cn/p/2023100601
本文作者:奔跑的蝸牛,轉載請註明原文鏈接:https://ntopic.cn