生成器
如果想延遲生成數值序列,可以使用生成器。
- 同步生成器 Synchronous,返回一個 Iterable 對象。
- 異步生成器 Asynchronous,返回一個 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);
}
}
更多參考Dart Language Asynchrony Support: Phase 2
可調用類
實現 call() 方法的類可以當作方法來調用。
class WannabeFunction {
call(String a, String b, String c) => '$a $b $c!';
}
main() {
var wf = new WannabeFunction();
var out = wf("Hi","there,","gang");
print('$out');
}
更多參考Emulating Functions in Dart
isolates
爲了發揮現代計算平臺的多核計算能力,dart 中提供 isolates。和 threads不同的是,isolates 不共享內存狀態,每個 isolate 都有自己的內存堆,保證isolate間不能互相訪問狀態,以避免代碼複雜化和降低出錯概率。
更多參考dart:isolate library documentation
Typedefs
在 Dart 語言中,方法也是對象。 使用 typedef, 或者 function-type alias 來爲方法命名, 然後可以使用命名的方法。 當把方法類型賦值給一個變量的時候,typedef 保留類型信息。
不適用 typedef,當把 f 賦值給 compare 的時候, 類型信息丟失了。
class SortedCollection {
Function compare;
SortedCollection(int f(Object a, Object b)) {
compare = f;
}
}
// Initial, broken implementation.
int sort(Object a, Object b) => 0;
main() {
SortedCollection coll = new SortedCollection(sort);
// 我們只知道 compare 是一個 Function 類型,
// 但是不知道具體是何種 Function 類型?
assert(coll.compare is Function);
}
使用typedef保留類型信息。
typedef int Compare(Object a, Object b);
class SortedCollection {
Compare compare;
SortedCollection(this.compare);
}
// Initial, broken implementation.
int sort(Object a, Object b) => 0;
main() {
SortedCollection coll = new SortedCollection(sort);
assert(coll.compare is Function);
assert(coll.compare is Compare);
}
注意:目前 typedefs 只能使用在 function 類型上,但是將來 可能會有變化。
另外,typedef 只是別名,所以dart提供了一種判斷任意 function 的類型的方法
typedef int Compare(int a, int b);
int sort(int a, int b) => a - b;
main() {
assert(sort is Compare); // True!
}
元數據註解
使用元數據可以給代碼添加額外的信息。元數據註解格式爲 @+編譯時常量(比如deprecated)/調用一個常量構造函數
有三個註解所有的 Dart 代碼都可以使用: @deprecated、 @override、 和 @proxy。@override 和 @proxy 示例請參考 Extending a class
class Television {
/// _Deprecated: Use [turnOn] instead._
@deprecated
void activate() {
turnOn();
}
/// Turns the TV's power on.
void turnOn() {
print('on!');
}
}
也可以自定義元數據註解
//定義註解
library todo;
class todo {
final String who;
final String what;
const todo(this.who, this.what);
}
//使用註解
import 'todo.dart';
@todo('seth', 'make this do something')
void doSomething() {
print('do something');
}
元數據可以在 library、 class、 typedef、 type parameter、constructor、 factory、 function、 field、 parameter、或者variable 聲明之前使用,也可以在 import 或者 export 指令之前使用。使用反射可以在運行時獲取元數據 信息。
註釋
- 單行註釋以 // 開始。
- 多行註釋以 /* 開始, */ 結尾。 多行註釋 可以 嵌套。
- 文檔註釋可以使用 /// 開始, 也可以使用 /** 開始 並以 */ 結束。文檔註釋中,編譯器忽略中括號以外的內容,中括號內可以引用classes、 methods、 fields、 top-level variables、 functions、 和 parameters。中括號裏面的名字使用 當前註釋出現地方的語法範圍查找對應的成員。