泛型
Dart的泛型会一直保留到运行时
Libraries & visibility
import和library指令可以帮助你创建模块和分享代码。Libraries不仅对外提供了API同时也包含一组隐私,所有以_开头的声明都只在Library可见。任何app可以当做一个library。
using libraries
通过import关键字导入某个命名空间的库(用URI声明库)
import 'dart:html';
对于内建的库,URI的scheme为dart:,其他库可以通过文件系统路径或scheme为package:指定。package:定位的资源有包管理器(pub tool)提供.
import 'package:test/test.dart';
库别名-as
当库中的类有冲突时,可以给库取个别名
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// Uses Element from lib1.
Element element1 = Element();
// Uses Element from lib2.
lib2.Element element2 = lib2.Element();
库的部分导入
// Import only foo.
import 'package:lib1/lib1.dart' show foo;
// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;
库的懒加载
可能需要懒加载的场景
- 减少app的启动时间
- 执行A/B测试时,可选的加载库
- 当库的使用频率很低时
懒加载步骤
- 使用deferred as
import 'package:greetings/hello.dart' deferred as hello;
- 用之前,调用loadLibrary()方法,多次调用该方法之后加载一次
Future greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
注:(后续懒加载规则可能会变化)
- 懒加载的库,只能在加载后才能使用
- 如果想在库加载之前使用接口,可以把它抽离出来,让懒加载的库和实际的库都引用
- Dart隐式的在将要懒加载的库中插入loadLibrary()函数,该函数返回Future对象。
异步编程
通过async和await的组合,让异步调用看起来和同步调用一样的。
- 函数虽然标记为async,但直到遇到await才会异步执行
- await语句可以在async函数中重复出现
- 每一个await expression都返回一个Future对象,如果不是,会被自动包装为Future对象
- await只能出现在有async的函数中
流处理
当你需要从流中获取值时,有两张方式
- 使用async和异步循环(await for)
//expression必须是Stream类型
await for (varOrType identifier in expression) {
// Executes each time the stream emits a value.
}
- 使用Stream API
生成器-Generators
Dart提供两种内建的生成器
- 同步生成器,返回Iterable对象
方式:用sync*标记函数,用yield派发值
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while(k < n) yield k++;
}
- 异步生成器,返回Stream对象
方式:用async*标记函数,用yield派发值
Stream<int> asynchronousNaturalsTo(int n) async* {
int k = 0;
while(k < n) yield k++;
}
如果需要递归,使用yield*,如:
Iterable<int> naturalsDownFrom(int n) async* {
if(n > 0) {
yield n;
yield* naturalsDownFrom(n -1);
}
}
callable classes
为了允许类像方法那样调用,需要定义一个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');
}
typedef
目前只适用于给function取别名,并且类型信息会一直保留到运行期间
typedef Compare = int Function(Object a, Object b);
class SortedCollection {
Compare compare;
SortedCollection(this.compare);
}
// Initial, broken implementation.
int sort(Object a, Object b) => 0;
void main() {
SortedCollection coll = SortedCollection(sort);
assert(coll.compare is Function);
assert(coll.compare is Compare);
}
也可包含泛型
typedef Compare<T> = int Function(T a, T b);
int sort(int a, int b) => a - b;
void main() {
assert(sort is Compare<int>); // True!
}
元数据-metadata
用于为代码提供额外的信息,元数据以@开头,跟随编译期常量(如deprecated、override)或常构造器方法的调用。
- dart提供@deprecated和@override
class Television {
/// _Deprecated: Use [turnOn] instead._
@deprecated
void activate() {
turnOn();
}
/// Turns the TV's power on.
void turnOn() {...}
}
- 自定义注解
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');
}
Metadata can appear before a library, class, typedef, type parameter, constructor, factory, function, field, parameter, or variable declaration and before an import or export directive. You can retrieve metadata at runtime using reflection.
Metadata can appear before a library, class, typedef, type parameter, constructor, factory, function, field, parameter, or variable declaration and before an import or export directive. You can retrieve metadata at runtime using reflection.
文档注释
单行以///开头,多行以/开头,连续的单行效果和多行是一样的。内容中用括弧([])包裹的内容为词法上下文对象的引用,如类、方法、字段、顶级变量、函数等等。
/// A domesticated South American camelid (Lama glama).
///
/// Andean cultures have used llamas as meat and pack
/// animals since pre-Hispanic times.
class Llama {
String name;
/// Feeds your llama [Food].
///
/// The typical llama eats one bale of hay per week.
void feed(Food food) {
// ...
}
/// Exercises your llama with an [activity] for
/// [timeLimit] minutes.
void exercise(Activity activity, int timeLimit) {
// ...
}
}
如上代码,通过dart文档生成工具生成的文档,[Food]将连接到Food的类文档
网友评论