=> (胖箭頭) 簡寫語法用于僅包含一條語句的函數(shù)。該語法在將匿名函數(shù)作為參數(shù)傳遞時非常有用:
flybyObjects.where((name) => name.contains('turn')).forEach(print);
類
class Spacecraft {
String name;
DateTime? launchDate;
int? get launchYear => launchDate?.year; // read-only non-final property
// 構(gòu)造函數(shù),帶有可以直接為成員變量賦值的語法糖。
Spacecraft(this.name, this.launchDate) {
// 這里可以實現(xiàn)初始化代碼。
}
// 命名構(gòu)造函數(shù),轉(zhuǎn)發(fā)到默認構(gòu)造函數(shù)。
Spacecraft.unlaunched(String name) : this(name, null);
// 方法。
void describe() {
print('Spacecraft: $name');
var launchDate = this.launchDate; // Type promotion doesn't work on getters.
if (launchDate != null) {
int years = DateTime.now().difference(launchDate).inDays ~/ 365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}
use:
var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
voyager.describe();
var voyager3 = Spacecraft.unlaunched('Voyager III');
voyager3.describe();
擴展類(繼承)Dart 支持單繼承。
class Orbiter extends Spacecraft {
double altitude;
Orbiter(String name, DateTime launchDate, this.altitude)
: super(name, launchDate);
}
Mixins
Mixin 是一種在多個類層次結(jié)構(gòu)中重用代碼的方法。下面的是聲明一個 Mixin 的做法:
mixin Piloted {
int astronauts = 1;
void describeCrew() {
print('Number of astronauts: $astronauts');
}
}
現(xiàn)在你只需使用 Mixin 的方式繼承這個類就可將該類中的功能添加給其它類。
class PilotedCraft extends Spacecraft with Piloted {
// ···
}
接口和抽象類
Dart 沒有 interface 關(guān)鍵字。相反,所有的類都隱式定義了一個接口。因此,任意類都可以作為接口被實現(xiàn)。
每一個類都隱式地定義了一個接口并實現(xiàn)了該接口,這個接口包含所有這個類的實例成員以及這個類所實現(xiàn)的其它接口。如果想要創(chuàng)建一個 A 類支持調(diào)用 B 類的 API 且不想繼承 B 類,則可以實現(xiàn) B 類的接口
class Person {
// In the interface, but visible only in this library.
final String _name;
// 構(gòu)造函數(shù)不在接口中。
Person(this._name);
// greet() 方法在接口中。
String greet(String who) => '你好,$who。我是$_name。';
}
// Person 接口的一個實現(xiàn)。
class Impostor implements Person {
String get _name => '';
String greet(String who) => '你好$who。你知道我是誰嗎?';
}
String greetBob(Person person) => person.greet('小芳');
void main() {
print(greetBob(Person('小蕓')));
print(greetBob(Impostor()));
}
你可以創(chuàng)建一個被任意具體類擴展(或?qū)崿F(xiàn))的抽象類。抽象類可以包含抽象方法(不含方法體的方法)。
abstract class Describable {
void describe();
void describeWithEmphasis() {
print('=========');
describe();
print('=========');
}
}
異步
使用 async 和 await 關(guān)鍵字可以讓你避免回調(diào)地獄(Callback Hell)并使你的代碼更具可讀性。
const oneSecond = Duration(seconds: 1);
// ···
Future<void> printWithDelay(String message) async {
await Future.delayed(oneSecond);
print(message);
}
相當于
Future<void> printWithDelay(String message) {
return Future.delayed(oneSecond).then((_) {
print(message);
});
}
如下一個示例所示,async 和 await 關(guān)鍵字有助于使異步代碼變得易于閱讀。
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(
'File for $object already exists. It was modified on $modified.');
continue;
}
await file.create();
await file.writeAsString('Start describing $object in this file.');
} on IOException catch (e) {
print('Cannot create description for $object: $e');
}
}
}
你也可以使用 async* 關(guān)鍵字,其可以為你提供一個可讀性更好的方式去生成 Stream。
Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
for (var object in objects) {
await Future.delayed(oneSecond);
yield '${craft.name} flies by $object';
}
}