dynamic关键字
1 2 3 4 5 6 7
| bool convertToBool(dynamic arg) { if (arg is bool) return arg; if (arg is String) return arg == 'true'; throw ArgumentError('Cannot convert $arg to a bool.'); }
|
泛型
Dart支持泛型类型,如List(整数列表)或List(任何类型的对象列表)
基本类型转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var one = int.parse('1'); assert(one == 1); var onePointOne = double.parse('1.1'); assert(onePointOne == 1.1); String oneAsString = 1.toString(); assert(oneAsString == '1'); String piAsString = 3.14159.toStringAsFixed(2); assert(piAsString == '3.14');
|
多行字符串
1 2 3 4 5 6 7 8 9 10 11 12 13
| var s1 = 'String ' 'concatenation' " works even over line breaks."; var s1 = ''' You can create multi-line strings like this one. '''; var s2 = """This is also a multi-line string.""";
|
原始字符串
1
| var s = r'In a raw string, not even \n gets special treatment.';
|
list
1 2 3 4 5 6 7
| var list = [1, 2, 3]; assert(list.length == 3); assert(list[1] == 2); list[1] = 1; assert(list[1] == 1); var constantList = const [1, 2, 3];
|
map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| 1, var gifts = { 'first': 'partridge', 'second': 'turtledoves', 'fifth': 'golden rings' }; var nobleGases = { 2: 'helium', 10: 'neon', 18: 'argon', }; 2, var gifts = Map(); gifts['first'] = 'partridge'; var nobleGases = Map(); nobleGases[2] = 'helium'; 3, var gifts = {'first': 'partridge'}; gifts['fourth'] = 'calling birds'; 4, final constantMap = const { 2: 'helium', 10: 'neon', 18: 'argon', };
|
Function
Dart是一种真正的面向对象语言,因此即使是函数也是对象并且具有类型Function。 这意味着函数可以分配给变量或作为参数传递给其他函数。您也可以像调用函数一样调用Dart类的实例。有关详细信息,请参阅可调用类。
1
| bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
|
可选参数
1 2 3 4 5 6 7 8 9 10
| 定义 void enableFlags({bool bold, bool hidden}) {...} 调用 enableFlags(bold: true, hidden: false); 必须的参数 import package:meta/meta.dart const Scrollbar({Key key, @required Widget child})
|
可选的位置参数
1 2 3 4 5 6 7
| String say(String from, String msg, [String device]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } return result; }
|
默认参数值
1 2 3 4 5
| void enableFlags({bool bold = false, bool hidden = false}) {...} enableFlags(bold: true);
|
函数当成参数传递(函数也是一个对象 Function对象)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 例 1 void printElement(int element) { print(element); } var list = [1, 2, 3]; list.forEach(printElement); 例 2 var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!'; assert(loudify('hello') == '!!! HELLO !!!');
|
闭包参数传值(相当于java中参数传入方法体中的匿名函数需要final)
方法体会持有外部参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Function makeAdder(num addBy) { return (num i) => addBy + i; } void main() { var add2 = makeAdder(2); var add4 = makeAdder(4); assert(add2(3) == 5); assert(add4(3) == 7); }
|
makeAdder方法中的代码片段会持有外部传入的addBy
Type test operators
Operator |
Meaning |
as |
Typecast (also used to specify library prefixes) |
is |
True if the object has the specified type |
is! |
False if the object has the specified type |
??= 当值为空时,才赋值
expr1 ?? expr2
expr1为空才计算expr2
?. 当为空时,整个表达式结果为空
级联
1 2 3 4
| querySelector('#confirm') ..text = 'Confirm' ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!'));
|
for in
1 2 3 4
| var collection = [0, 1, 2]; for (var x in collection) { print(x); }
|
try catch
throw
1 2 3
| throw FormatException('Expected at least 1 section'); throw 'Out of llamas!'; void distanceTo(Point other) => throw UnimplementedError();
|
try
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| 特定异常 try { breedMoreLlamas(); } on OutOfLlamasException { buyMoreLlamas(); } 先捕获特定异常, 然后捕获带异常对象的异常 最后捕获剩余的异常 try { breedMoreLlamas(); } on OutOfLlamasException { buyMoreLlamas(); } on Exception catch (e) { print('Unknown exception: $e'); } catch (e) { print('Something really unknown: $e'); } 除了异常对象,还可以获取堆栈信息 try { } on Exception catch (e) { print('Exception details:\n $e'); } catch (e, s) { print('Exception details:\n $e'); print('Stack trace:\n $s'); } void misbehave() { try { dynamic foo = true; print(foo++); } catch (e) { print('misbehave() partially handled ${e.runtimeType}.'); rethrow; } }
|
类
// If p is non-null, set its y value to 4.
p?.y = 4;
构造对象
1 2 3 4 5 6 7
| var p1 = Point(2, 2); var p2 = Point.fromJson({'x': 1, 'y': 2}); var p = const ImmutablePoint(2, 2);
|
获取类型
1
| print('The type of a is ${a.runtimeType}');
|
构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Point { num x, y; Point(this.x, this.y); } 命名构造函数 class Point { num x, y; Point(this.x, this.y); Point.origin() { x = 0; y = 0; } }
|
子类不继承父类的构造函数
父类没有默认的构造函数,子类写自己的构造函数时,需要使用 :调用一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Person { String firstName; Person.fromJson(Map data) { print('in Person'); } } class Employee extends Person { Employee.fromJson(Map data) : super.fromJson(data) { print('in Employee'); } }
|
默认参数
1 2 3 4 5 6 7 8 9 10
| Point.fromJson(Map<String, num> json) : x = json['x'], y = json['y'] { print('In Point.fromJson(): ($x, $y)'); } Point.withAssert(this.x, this.y) : assert(x >= 0) { print('In Point.withAssert(): ($x, $y)'); }
|
重定向构造函数
1 2 3 4 5 6 7 8 9
| class Point { num x, y; Point(this.x, this.y); Point.alongXAxis(num x) : this(x, 0); }
|
常量构造函数
1 2 3 4 5 6 7 8
| class ImmutablePoint { static final ImmutablePoint origin = const ImmutablePoint(0, 0); final num x, y; const ImmutablePoint(this.x, this.y); }
|
工厂构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Logger { final String name; bool mute = false; static final Map<String, Logger> _cache = <String, Logger>{}; factory Logger(String name) { if (_cache.containsKey(name)) { return _cache[name]; } else { final logger = Logger._internal(name); _cache[name] = logger; return logger; } } Logger._internal(this.name); void log(String msg) { if (!mute) print(msg); } } var logger = Logger('UI'); logger.log('Button clicked');
|
方法
get set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Rectangle { num left, top, width, height; Rectangle(this.left, this.top, this.width, this.height); num get right => left + width; set right(num value) => left = value - width; num get bottom => top + height; set bottom(num value) => top = value - height; } void main() { var rect = Rectangle(3, 4, 20, 15); assert(rect.left == 3); rect.right = 12; assert(rect.left == -8); }
|
接口
每个类既是类,又是接口,如果你想不使用类的实现,但是需要它的类型,就是使用implements,否则就extends
方法未实现时会被调用 noSuchMethod
1 2 3 4 5 6 7 8 9
| class A { @override void noSuchMethod(Invocation invocation) { print('You tried to use a non-existent member: ' + '${invocation.memberName}'); } }
|
mixins 语法(高级)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Musician extends Performer with Musical { } class Maestro extends Person with Musical, Aggressive, Demented { Maestro(String maestroName) { name = maestroName; canConduct = true; } } mixin Musical { bool canPlayPiano = false; bool canCompose = false; bool canConduct = false; void entertainMe() { if (canPlayPiano) { print('Playing piano'); } else if (canConduct) { print('Waving hands'); } else { print('Humming to self'); } } }
|
泛型示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var names = <String>['Seth', 'Kathy', 'Lars']; var pages = <String, String>{ 'index.html': 'Homepage', 'robots.txt': 'Hints for web robots', 'humans.txt': 'We are people, not machines' }; To specify one or more types when using a constructor, put the types in angle brackets (<...>) just after the class name. For example: var names = List<String>(); names.addAll(['Seth', 'Kathy', 'Lars']); var nameSet = Set<String>.from(names); var views = Map<int, View>();
|
打印泛型类型
1 2 3 4 5 6
| class Foo<T extends SomeBaseClass> { String toString() => "Instance of 'Foo<$T>'"; } class Extender extends SomeBaseClass {...}
|
导入库
库冲突
1 2
| import 'package:lib1/lib1.dart'; import 'package:lib2/lib2.dart' as lib2;
|
导入库的一部分
1 2 3 4 5
| import 'package:lib1/lib1.dart' show foo; import 'package:lib2/lib2.dart' hide foo;
|
懒加载库
1 2 3 4 5
| import 'package:greetings/hello.dart' deferred as hello; Future greet() async { await hello.loadLibrary(); hello.printGreeting(); }
|
async and await
要使用await 必须在标有async的函数上进行
1 2 3 4 5 6
| Future checkVersion() async { var version = await lookUpVersion(); } Future<String> lookUpVersion() async => '1.0.0';
|
处理流
1 2 3
| await for (varOrType identifier in expression) { }
|
Generators(迭代生成器)
同步的Generators
1 2 3 4
| Iterable<int> naturalsTo(int n) sync* { int k = 0; while (k < n) yield k++; }
|
异步的Generators
1 2 3 4
| Stream<int> asynchronousNaturalsTo(int n) async* { int k = 0; while (k < n) yield k++; }
|
可调用的类
需要实现call方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 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 函数类型(函数式变成基础) ``` dart typedef Compare = int Function(Object a, Object b); class SortedCollection { Compare compare; SortedCollection(this.compare); } int sort(Object a, Object b) => 0; void main() { SortedCollection coll = SortedCollection(sort); assert(coll.compare is Function); assert(coll.compare is Compare); }
|
定义元数据
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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'); }
|
https://www.dartlang.org/guides/language/language-tour