var荷辕,dynamic,Object
var
如果沒有初始化件豌,可以變成任何類型疮方。
var a;
a = 'ducafecat';
a = 123;
a = true;
若果有初始值,則類型會(huì)被鎖定茧彤,下例會(huì)報(bào)錯(cuò):
var a = 'ducafecat';
a = 123;
報(bào)錯(cuò):
編譯報(bào)錯(cuò):
編譯,運(yùn)行均正常:
Object
動(dòng)態(tài)任意類型惫谤,編譯階段檢查類型
Object a = 'doucafecat';
a = 123;
a = [2222];
編譯運(yùn)行均正常:
dynamic
動(dòng)態(tài)任意類型溜歪,編譯階段不檢查類型
dynamic a = 'doucafecat';
a = 123;
a = [1111];
編譯運(yùn)行均正常:
總結(jié)
var 初始化確定類型后不可更改類型, Object 以及dynamic 可以更改類型
Object 編譯階段檢查類型, 而 dynamic 編譯階段不檢查類型调衰。
var實(shí)際上是編譯期拋給我們的“語法糖”自阱,一旦被編譯,
編譯期會(huì)自動(dòng)匹配var 變量的實(shí)際類型萝喘,并用實(shí)際類型來替換該變量的申明琼懊,
這看上去就好像我們在編碼的時(shí)候是用實(shí)際類型進(jìn)行申明的爬早。
而dynamic被編譯后,實(shí)際是一個(gè) object類型醉旦,
只不過編譯器會(huì)對dynamic類型進(jìn)行特殊處理桨啃,
讓它在編譯期間不進(jìn)行任何的類型檢查,而是將類型檢查放到了運(yùn)行期匈棘。
異步相關(guān)
await for
await for (variable declaration in expression) {
// Executes each time the stream emits a value.
}
表達(dá)式 的值必須有Stream 類型(流類型)析命。
執(zhí)行過程如下:
1.在 stream 發(fā)出一個(gè)值之前等待
2.執(zhí)行 for 循環(huán)的主體,把變量設(shè)置為發(fā)出的值鹃愤。
3.重復(fù) 1 和 2,直到 Stream 關(guān)閉
如果要停止監(jiān)聽 stream 瘩将,你可以使用 break 或者 return 語句,跳出循環(huán)并取消來自 stream 的訂閱 肠仪。
main() async {
...
await for (var request in requestServer) {
handleRequest(request);
}
...
}
sync * 同步生成器
Iterable naturalsTo(n) sync* {
print("Begin");
int k = 0;
while (k < n) yield k++;
print("End");
}
main() {
var it = naturalsTo(3).iterator;
while(it.moveNext()) {
print(it.current);
}
}
運(yùn)行結(jié)果:
Begin
0
1
2
End
當(dāng)調(diào)用naturalsTo的時(shí)候藤韵,會(huì)立即返回Iterable(很像async函數(shù)立即返回Future)熊经,并且可以通過Iterable提取iterator。在有代碼調(diào)用moveNext前匹涮,函數(shù)主體并不會(huì)執(zhí)行槐壳。yield(生成)用于聲明一個(gè)求值表達(dá)式,當(dāng)?shù)谝淮芜\(yùn)行函數(shù)的時(shí)候雳攘,代碼會(huì)執(zhí)行到y(tǒng)ield關(guān)鍵字聲明的位置枫笛,并暫停執(zhí)行,moveNext會(huì)返回true給調(diào)用者刑巧。函數(shù)會(huì)在下次調(diào)用moveNext的時(shí)候恢復(fù)執(zhí)行。當(dāng)循環(huán)結(jié)束的時(shí)候吠冤,函數(shù)會(huì)隱式地執(zhí)行return恭理,這會(huì)使迭代終止,moveNext返回false薄风。
async * 異步生成器
import 'dart:async';
Stream asynchronousNaturalsTo(n) async* {
print("Begin");
int k = 0;
while (k < n) yield k++;
print("End");
}
main() {
asynchronousNaturalsTo(3).listen((v) {
print(v);
});
}
運(yùn)行結(jié)果:
Begin
0
1
2
End
當(dāng)運(yùn)行asynchronousNaturalsTo的時(shí)候拍嵌,會(huì)立即返回Stream,但函數(shù)體并不會(huì)執(zhí)行撇他,就像sync*生成器和async函數(shù)一樣。一旦開始listen監(jiān)聽數(shù)據(jù)流困肩,函數(shù)體會(huì)開始執(zhí)行。當(dāng)執(zhí)行到y(tǒng)ield關(guān)鍵字的時(shí)候勇劣,會(huì)將yield聲明的求值表達(dá)式的計(jì)算結(jié)果添加到Stream數(shù)據(jù)流中潭枣。異步生成器沒有必要暫停,因?yàn)閿?shù)據(jù)流可以通過StreamSubscription進(jìn)行控制命咐。需注意的是谐岁,數(shù)據(jù)流不能重復(fù)監(jiān)聽。
暫停
import 'dart:async';
Stream get asynchronousNaturals async* {
print("Begin");
int k = 0;
while (k < 3) {
print("Before Yield");
yield k++;
}
print("End");
}
main() {
StreamSubscription subscription = asynchronousNaturals.listen(null);
subscription.onData((value) {
print(value);
subscription.pause();
});
}
運(yùn)行結(jié)果:
Begin
Before Yield
0
Before Yield
Completer
class AsyncOperation {
Completer _completer = new Completer();
Future<T> doOperation() {
_startOperation();
return _completer.future; // Send future object back to client.
}
// Something calls this when the value is ready.
void _finishOperation(T result) {
_completer.complete(result);
}
// If something goes wrong, call this.
void _errorHappened(error) {
_completer.completeError(error);
}}