生成器
如果想延迟生成数值序列,可以使用生成器。
- 同步生成器 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。中括号里面的名字使用 当前注释出现地方的语法范围查找对应的成员。