var,dynamic,Object
var
如果没有初始化,可以变成任何类型。
var a;
a = 'ducafecat';
a = 123;
a = true;
若果有初始值,则类型会被锁定,下例会报错:
var a = 'ducafecat';
a = 123;
报错:
编译报错:
编译,运行均正常:
Object
动态任意类型,编译阶段检查类型
Object a = 'doucafecat';
a = 123;
a = [2222];
编译运行均正常:
dynamic
动态任意类型,编译阶段不检查类型
dynamic a = 'doucafecat';
a = 123;
a = [1111];
编译运行均正常:
总结
var 初始化确定类型后不可更改类型, Object 以及dynamic 可以更改类型
Object 编译阶段检查类型, 而 dynamic 编译阶段不检查类型。
var实际上是编译期抛给我们的“语法糖”,一旦被编译,
编译期会自动匹配var 变量的实际类型,并用实际类型来替换该变量的申明,
这看上去就好像我们在编码的时候是用实际类型进行申明的。
而dynamic被编译后,实际是一个 object类型,
只不过编译器会对dynamic类型进行特殊处理,
让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期。
异步相关
await for
await for (variable declaration in expression) {
// Executes each time the stream emits a value.
}
表达式 的值必须有Stream 类型(流类型)。
执行过程如下:
1.在 stream 发出一个值之前等待
2.执行 for 循环的主体,把变量设置为发出的值。
3.重复 1 和 2,直到 Stream 关闭
如果要停止监听 stream ,你可以使用 break 或者 return 语句,跳出循环并取消来自 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);
}
}
运行结果:
Begin
0
1
2
End
当调用naturalsTo的时候,会立即返回Iterable(很像async函数立即返回Future),并且可以通过Iterable提取iterator。在有代码调用moveNext前,函数主体并不会执行。yield(生成)用于声明一个求值表达式,当第一次运行函数的时候,代码会执行到yield关键字声明的位置,并暂停执行,moveNext会返回true给调用者。函数会在下次调用moveNext的时候恢复执行。当循环结束的时候,函数会隐式地执行return,这会使迭代终止,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);
});
}
运行结果:
Begin
0
1
2
End
当运行asynchronousNaturalsTo的时候,会立即返回Stream,但函数体并不会执行,就像sync*生成器和async函数一样。一旦开始listen监听数据流,函数体会开始执行。当执行到yield关键字的时候,会将yield声明的求值表达式的计算结果添加到Stream数据流中。异步生成器没有必要暂停,因为数据流可以通过StreamSubscription进行控制。需注意的是,数据流不能重复监听。
暂停
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();
});
}
运行结果:
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);
}}