liutong 2019-12-12
// 导入(import) // 导入核心库 //导入外部库 import 'package:test_api/test_api.dart'; // 导入文件 //import 'path/test.dart'; // 每个应用都有一个 main() 函数 void main() { // 你好,世界 // 使用顶层函数 print() 来将一段文本输出显示到控制台 print('Hello, World!'); // 变量 // 虽然 Dart 是代码类型安全的语言,但是由于其支持类型推断,因此大多数变量不需要显式地指定类型 var name = '天空之城'; var year = 1977; var antennaDiameter = 3.7; var flybyObjects = ['木星', '土星', '天王星', '海王星']; var image = { 'tags': ['木星'], 'url': '//path//ex.jpg', }; // 流程控制语句 // Dart 支持常用的流程控制语句 if (year >= 2001) { print('21世纪'); } else if (year >= 1901) { print('20世纪'); } for (var object in flybyObjects) { print(object); } for (var month = 1; month <= 12; ++month){ print(month); } while (year < 2016) { year += 1; } // 调用函数 var result = fibonacci(20); print(result); // =>(胖箭头) // 这种简写语法用于仅包含一条语句的函数。该语法在将匿名函数作为参数传递时非常有用 flybyObjects.where((name) => name.contains('土星')).forEach(print); // 注释 // 这是一个普通的单行注释。 /// 这是一个文档注释。 /// 文档注释用于为库、类以及类的成员添加注释。 /// 像 IDE 和 dartdoc 这样的工具可以专门处理文档注释。这很重要! /* 也可以像这样使用单斜杠和星号的注释方式 */ // 使用类 var voyager = Spacecraft('旅行者一号', DateTime(1977, 5, 5)); voyager.describe(); var voyager3 = Spacecraft.unlaunched('旅行者三号'); voyager3.describe(); } // 函数 // 建议为每个函数的参数以及返回值都指定类型 int fibonacci(int n) { if (n == 0 || n == 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); } // 类 // 展示了一个包含三个属性、两个构造函数以及一个方法的类。其中一个属性不能直接赋值,因此它被定义为一个 getter 方法(而不是变量)。 class Spacecraft { String name; DateTime launchDate; // 构造函数,带有可以直接为成员变量赋值的语法糖 Spacecraft(this.name, this.launchDate) { // 实现初始化代码 } // 命名构造函数,转发到默认构造函数 Spacecraft.unlaunched(String name) : this(name, null); // 只读的非final的属性 int get launchYear => launchDate?.year; // 方法 void describe() { print('宇宙飞船:$name'); if (launchDate != null) { int years = DateTime.now().difference(launchDate).inDays ~/ 365; print('发射时间:$launchYear ($years years ago)'); } else { print('尚未发射!'); } } } // 继承类,Dart支持单继承 class Orbiter extends Spacecraft { num altitude; Orbiter(String name, DateTime launchDate, this.altitude) : super(name, launchDate); } // Mixins, 它是一种在多个类层次结构中重用代码的方法 class Piloted { int astronauts = 1; void describeCrew() { print('宇航员人数:$astronauts'); } } // 使用 Mixin 的方式继承这个类就可将该类中的功能添加给其它类 class PilotedCraft extends Spacecraft with Piloted { // } // 接口和抽象类 // Dart 没有 interface 关键字。相反,所有的类都隐式定义了一个接口。因此,任意类都可以作为接口被实现。 class MockSpaceship implements Spacecraft { // } // 创建一个被任意具体类扩展(或实现)的抽象类。抽象类可以包含抽象方法(不含方法体的方法)。 abstract class Describable { void describe(); void describeWithEmphasis() { print('========='); describe(); print('========='); } } // 异步 // 使用 async 和 await 关键字可以让你避免回调地狱(Callback Hell)并使你的代码更具可读性 const oneSecond = Duration(seconds: 1); // ... Future<void> printWithDelay(String message) async { await Future.delayed(oneSecond); print(message); } // async 和 await 关键字有助于使异步代码变得易于阅读 Future<void> createDescriptions(Iterable<String> objects) async { for (var object in objects) { try { var file = File('$object.txt'); if (await file.exists()) { var modified = await file.lastModified(); print('文件$object已经存在,它上一次修改时间为 $modified。'); continue; } await file.create(); await file.writeAsString('开始在此文件中描述 $object。'); } on IOException catch (e) { print('不能为 $object 创建描述:$e'); } } } // 也可以使用 async* 关键字,其可以为你提供一个可读性更好的方式去生成 Stream。 Stream<String> report(Spacecraft craft, Iterable<String> objects) async* { for (var object in objects) { await Future.delayed(oneSecond); yield '${craft.name} 由 $object 飞行。'; } } // 异常 // 使用 throw 关键字抛出一个异常 if (astronauts == 0) { throw StateError('没有宇航员'); } // 使用 try 语句配合 on 或 catch(两者也可同时使用)关键字来捕获一个异常 try { for (var object in flybyObjects) { var description = await File('$object.txt').readAsString(); print(description); } } on IOException catch (e) { print('无法描述该对象:$e'); } finally { flybyObjects.clear(); } // 上述代码是异步的;同步代码以及异步函数中得代码都可以使用 try 捕获异常。