# Dart 初试 ## hello `main`函数, `print`函数内省. ```dart void main() { var name = "tom"; print("hello, ${name}"); } ``` ## `dynamic` 类型推断. ```dart var name = "tom"; // == String name = "tom"; ``` 定义一个类型可变的变量. ```dart dynamic name = "tom"; print("hello, ${name}"); name = 1; print("int? ${name}"); ``` ## 类型 所有变量都是引用, 因此所有类型默认值都是`null`, 包括数值. ```dart int x; print("default int ${x}"); // default int null ``` ### 内置类型 - num - int (64bit) - double (64bit) - string - utf-16 - bool - true/false - list - `var x = []` - `List x = []` - `.length` - `x[i] = y` - map - `var m = {k: "v"}` - `Map m = {}` - `.length` - `m["key"] = value` ## 常量 编译期常量, `const`, `static const`. 常(变)量. > const x = []; 常值. > final x = const []; ## 函数 ### 参数 - named 参数 - positional 参数 - optional 参数 ```dart int sum0({int x = 1, int y = 2}) { return x + y; } int sum1(int x, int y, [int z = 4]) { return x + y + z; } sum0(x: 1); sum1(1, 2); ``` ### first-class 匿名函数: ```dart ([[Type] param1[,...]]) { block; }; ``` ```dart var upper = (msg) => msg.toUpperCase(); var upper2 = (msg) { return msg.toUpperCase(); }; ``` ### 函数对象 `Function` 与`词法闭包`的例子一起看 ## 词法作用域 `{}` ## 词法闭包 ```dart Function makeAdder(int x) { return (int i) => x + i; } var adder2 = makeAdder(2); adder2(3); // == 5 ``` ## 算符 - `~/` 整除 - `?.` - `v?.x` - 如果`v`不为`null`, 访问`x`字段. 可以避免exception. - `??` - `expr1 ?? expr2` - 等价于py中的, `expr1 or expr2` - `??=` - `b ??= value` - 如果`b`为`null`, 则赋值value, 否则什么都不做. - `..` - cascade - `is`/`is!` - 类型assert - `a is TypeA` - `a ? b: c` ## 异常 可以抛出任何类型数据. ```dart throw FormatException(""); throw 'ABC' ``` ### try-catch ```dart try { } on XException { } on YException { } catch(e) { } ``` 这里`catch`是默认handler. `rethrow`在handler里重新抛出已经handle的异常. `finally`永远执行, 不论有没有把异常抓住. ## class 获取一个object的类型. > obj.runtimeType 构造函数不能被继承, named构造函数, 类似于工厂方法. 可以调用父类的构造函数(因为父类构造函数的创建时间先于子类). ```dart class Employee extends Person { Employee : super.fromJson(getDefaultData()); } ``` 初始化列表,类似于c++. ```dart Point.fromJson(Map json) : x = json['x'], y = json['y'] { // code block } ``` `factory`机制引进的比较奇怪, 没想到太多好处. `cache`应该显式的做. ## mixin 可以针对某一类型, 提供`mixin`. ```dart mixin MusicalPerformer on Musician {} ``` 使用`with`应用. ```dart class C extends A with E, F, G {} ``` TODO 多个`mixin`中, 字段有重名怎么处理? ## 泛型 类似java的泛型. ### 协变 ```dart class Foo {} ``` ### 方法 ```dart T add(T x, T y) { return x + y; } add(1, 2); ``` ## import 别名 > import 'xxx' as bbb; 特定import > import 'xxx' show x; 排除import > import 'xxx' hide y; ### 延迟import > import 'xxx' defered as y; 第一次需要的时候才会加载. ## String ### 判空 ```dart var s = ""; (s == null) == false; s.isEmpty == true; ``` ### StringBuffer ```dart var sb = StringBuffer(); sb ..write("hello,") ..writeAll(["t", "o", "m"]) ..writeln(); s = sb.toString(); ``` ### Join ```dart s = ["hello", "world"].join(","); ``` ## Async 一个整数生成器, 一个异步求和函数, 求得结果. ```dart import 'dart:async'; Future sumStream(Stream s) async { var sum = 0; await for (var v in s) { sum += v; } return sum; } Stream countStream() async* { for (int i = 0; i <= 1000; i++) { yield i; } } main() async { var sum = await sumStream(countStream()); print(sum); } ``` 几个关键字`async`, `async*`, `await`. `async`, `async*`用于标注函数, 当函数体中包含`await`, 那么这个函数就需要标注为`async`. `async*`异步生成器, `sync*`同步生成器. ### Stream 两种 - single subscription - 只能被`listen`一次. - broadcast 实际中能否简单的把stream和生成器等价? ## Event Loop https://webdev.dartlang.org/articles/performance/event-loop 实现异步代码的核心逻辑. ## isolate `isolate`是dart中的一个控制单元, 其内部的代码顺序执行,拥有自己的内存. 多个`isolate`之间内存是隔离的,也没有共享内存机制, 通信依靠`Port`进行. 可以理解为一个`Actor`的dart实现.