1网严、前言:
最近在學(xué)習(xí)Flutter控妻,作為Flutter的編程語言鸥印,Dart語言語法的學(xué)習(xí)自然就編程重中之重。本文主要記錄自己在學(xué)習(xí)Dart語法時(shí)的一些重要概念和學(xué)習(xí)路線蹬音,在學(xué)習(xí)官方文檔時(shí)上煤,對自己覺得重要的或者需要標(biāo)記的語法知識(shí)點(diǎn)進(jìn)行匯總和整理而成,方便后續(xù)進(jìn)行語法整體概念的回顧和復(fù)習(xí)著淆。如果同時(shí)能對其他人有所幫助那就更好不過了劫狠,同時(shí)也建議對Dart感興趣的同學(xué)拴疤,去查看Dart語法的官方文檔。
2独泞、 Important concepts(重要的概念)
所有能夠使用變量引用的都是對象呐矾, 每個(gè)對象都是一個(gè)類的實(shí)例。在 Dart 中 甚至連 數(shù)字懦砂、方法和
null
都是對象蜒犯。所有的對象都繼承于 Object類。使用靜態(tài)類型(例如前面示例中的
num
) 可以更清晰的表明你的意圖荞膘,并且可以讓靜態(tài)分析工具來分析你的代碼罚随, 但這并不是牽制性的。(在調(diào)試代碼的時(shí)候你可能注意到 沒有指定類型的變量的類型為dynamic
羽资。)Dart 在運(yùn)行之前會(huì)先解析你的代碼淘菩。你可以通過使用 類型或者編譯時(shí)常量來幫助 Dart 去捕獲異常以及 讓代碼運(yùn)行的更高效。
Dart 支持頂級方法 (例如
main()
)屠升,同時(shí)還支持在類中定義函數(shù)潮改。 (靜態(tài)函數(shù)和實(shí)例函數(shù))。 你還可以在方法中定義方法 (嵌套方法或者局部方法)弥激。同樣进陡,Dart 還支持頂級變量,以及 在類中定義變量(靜態(tài)變量和實(shí)例變量)微服。 實(shí)例變量有時(shí)候被稱之為域(Fields)或者屬性(Properties)趾疚。
和 Java 不同的是,Dart 沒有
public
以蕴、protected
糙麦、 和private
關(guān)鍵字。如果一個(gè)標(biāo)識(shí)符以 (_) 開頭丛肮,則該標(biāo)識(shí)符 在庫內(nèi)是私有的赡磅。詳情請參考:庫和可見性。標(biāo)識(shí)符可以以字母或者 _ 下劃線開頭宝与,后面可以是 其他字符和數(shù)字的組合焚廊。
有時(shí)候 表達(dá)式 expression 和 語句 statement 是有區(qū)別的,所以這種情況我們會(huì)分別指明每種情況习劫。
Dart 工具可以指出兩種問題:警告和錯(cuò)誤咆瘟。 警告只是說你的代碼可能有問題, 但是并不會(huì)阻止你的代碼執(zhí)行诽里。 錯(cuò)誤可以是編譯時(shí)錯(cuò)誤也可以是運(yùn)行時(shí)錯(cuò)誤袒餐。遇到編譯時(shí)錯(cuò)誤時(shí),代碼將 無法執(zhí)行;運(yùn)行時(shí)錯(cuò)誤將會(huì)在運(yùn)行代碼的時(shí)候?qū)е乱粋€(gè)異常灸眼。
3卧檐、 Keywords(關(guān)鍵字)
1 帶有上標(biāo) 1 的關(guān)鍵字是 內(nèi)置關(guān)鍵字。避免把內(nèi)置關(guān)鍵字當(dāng)做標(biāo)識(shí)符使用焰宣。 也不要把內(nèi)置關(guān)鍵字 用作類名字和類型名字霉囚。 有些內(nèi)置關(guān)鍵字是為了方便把 JavaScript 代碼移植到 Dart 而存在的。 例如匕积,如果 JavaScript 代碼中有個(gè)變量的名字為
factory
佛嬉, 在移植到 Dart 中的時(shí)候,你不必重新命名這個(gè)變量闸天。2 帶有上標(biāo) 2 的關(guān)鍵字,是在 Dart 1.0 發(fā)布以后又新加的斜做,用于 支持異步相關(guān)的特性苞氮。 你不能在標(biāo)記為
async
、async*
瓤逼、或者sync*
的方法體內(nèi) 使用async
笼吟、await
、或者yield
作為標(biāo)識(shí)符霸旗。 詳情請參考:異步支持贷帮。所以其他單詞都是 保留詞。 你不能用保留詞作為關(guān)鍵字诱告。
4撵枢、Variables(變量)
Default value(默認(rèn)值)
- 未初始化的變量默認(rèn)值為null,數(shù)字也是對象精居,未初始化的數(shù)字默認(rèn)值也為null
- Optional types(可選的類型)
> var name = 'Bob';
> String name = 'Bob';
> 即聲明變量時(shí)锄禽,既可以顯式聲明其類型,也可以不聲明其類型靴姿。對于局部變量沃但,推薦使用var,即不指明其類型
Final and const
- 如果你以后不打算修改一個(gè)變量佛吓,使用 final 或者 const宵晚。 一個(gè) final 變量只能賦值一次;一個(gè) const 變量是編譯時(shí)常量维雇。 (Const 變量同時(shí)也是 final 變量淤刃。) 頂級的 final 變量或者類中的 final 變量在 第一次使用的時(shí)候初始化。
- 實(shí)例變量可以為 final 但是不能是 const 谆沃。
- const 關(guān)鍵字不僅僅只用來定義常量钝凶。 有可以用來創(chuàng)建不變的值, 還能定義構(gòu)造函數(shù)為 const 類型的,這種類型 的構(gòu)造函數(shù)創(chuàng)建的對象是不可改變的耕陷。任何變量都可以有一個(gè)不變的值掂名。
// Note: [] creates an empty list.
// const [] creates an empty, immutable list (EIA).
var foo = const []; // foo is currently an EIA.
final bar = const []; // bar will always be an EIA.
const baz = const []; // baz is a compile-time constant EIA.
// You can change the value of a non-final, non-const variable,
// even if it used to have a const value.
foo = [];
// You can't change the value of a final or const variable.
// bar = []; // Unhandled exception.
// baz = []; // Unhandled exception.
5、Built-in types(內(nèi)置的類型)
Dart 內(nèi)置支持下面這些類型:
- numbers
- strings
- booleans
- lists (也被稱之為 arrays)
- maps
- runes (用于在字符串中表示 Unicode 字符)
- symbols
Numbers(數(shù)值)
- int : 整數(shù)值哟沫,其取值通常位于 -253 和 253 之間饺蔑。
- double : 64-bit (雙精度) 浮點(diǎn)數(shù),符合 IEEE 754 標(biāo)準(zhǔn)嗜诀。
下面是字符串和數(shù)字之間轉(zhuǎn)換的方式:
// String -> int
var one = int.parse('1');
assert(one == 1);
// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);
// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
Strings(字符串)
可以在字符串中使用表達(dá)式猾警,用法是這樣的: ${expression}
var s = 'string interpolation';
assert('Dart has $s, which is very handy.' ==
'Dart has string interpolation, ' +
'which is very handy.');
assert('That deserves all caps. ' +
'${s.toUpperCase()} is very handy!' ==
'That deserves all caps. ' +
'STRING INTERPOLATION is very handy!');
使用三個(gè)單引號或者雙引號也可以 創(chuàng)建多行字符串對象:
var s1 = '''
You can create
multi-line strings like this one.
''';
var s2 = """This is also a
multi-line string.""";
通過提供一個(gè) r 前綴可以創(chuàng)建一個(gè) “原始 raw” 字符串:
var s = r"In a raw string, even \n isn't special.";
Booleans(布爾值)
var name = 'Bob';
if (name) {
// Prints in JavaScript, not in Dart.
print('You have a name!');
}
Dart 有一個(gè)名字為 bool 的類型。 只有兩個(gè)對象是布爾類型的:true 和 false 所創(chuàng)建的對象隆敢, 這兩個(gè)對象也都是編譯時(shí)常量发皿。當(dāng) Dart 需要一個(gè)布爾值的時(shí)候,只有 true 對象才被認(rèn)為是 true拂蝎。 所有其他的值都是 flase穴墅。這點(diǎn)和 JavaScript 不一樣,在 JavaScript 中 name 是非 null 對象所以認(rèn)為是 true
Lists(列表)
var list = [1, 2, 3];
assert(list.length == 3);
assert(list[1] == 2);
list[1] = 1;
assert(list[1] == 1);
Maps
var gifts = {
// Keys Values
'first' : 'partridge',
'second': 'turtledoves',
'fifth' : 'golden rings'
};
var nobleGases = {
// Keys Values
2 : 'helium',
10: 'neon',
18: 'argon',
};
var gifts = new Map();
gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';
var nobleGases = new Map();
nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds'; // Add a key-value pair
Runes
在 Dart 中温自,runes 代表字符串的 UTF-32 code points玄货。
Symbols
使用 Symbol 字面量來獲取標(biāo)識(shí)符的 symbol 對象,也就是在標(biāo)識(shí)符 前面添加一個(gè) # 符號:
#radix
#bar
Symbol 字面量定義是編譯時(shí)常量悼泌。
6松捉、Functions(方法)
Dart 是一個(gè)真正的面向?qū)ο笳Z言,方法也是對象并且具有一種 類型馆里, Function
隘世。 這意味著,方法可以賦值給變量鸠踪,也可以當(dāng)做其他方法的參數(shù)以舒。 也可以把 Dart 類的實(shí)例當(dāng)做方法來調(diào)用。
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
Optional parameters(可選參數(shù))
- Optional named parameters(可選命名參數(shù))
/// Sets the [bold] and [hidden] flags to the values
/// you specify.
enableFlags({bool bold, bool hidden}) {
// ...
}
- Optional positional parameters(可選位置參數(shù))
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
assert(say('Bob', 'Howdy', 'smoke signal') ==
'Bob says Howdy with a smoke signal');
- Default parameter values(默認(rèn)參數(shù)值)
/// Sets the [bold] and [hidden] flags to the values you
/// specify, defaulting to false.
void enableFlags({bool bold = false, bool hidden = false}) {
// ...
}
// bold will be true; hidden will be false.
enableFlags(bold: true);
String say(String from, String msg,
[String device = 'carrier pigeon', String mood]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
if (mood != null) {
result = '$result (in a $mood mood)';
}
return result;
}
assert(say('Bob', 'Howdy') ==
'Bob says Howdy with a carrier pigeon');
The main() function(入口函數(shù))
沒啥要說的
Functions as first-class objects(一等方法對象)
可以把方法當(dāng)做參數(shù)調(diào)用另外一個(gè)方法慢哈。例如:
printElement(element) {
print(element);
}
var list = [1, 2, 3];
// Pass printElement as a parameter.
list.forEach(printElement);
方法也可以賦值給一個(gè)變量:
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');
Anonymous functions(匿名方法)
下面的代碼定義了一個(gè)參數(shù)為i (該參數(shù)沒有指定類型)的匿名函數(shù)蔓钟。
var list = ['apples', 'oranges', 'grapes', 'bananas', 'plums'];
list.forEach((i) {
print(list.indexOf(i).toString() + ': ' + i);
});
如果方法只包含一個(gè)語句,可以使用胖箭頭語法縮寫
list.forEach((i) => print(list.indexOf(i).toString() + ': ' + i));
Lexical scope(靜態(tài)作用域)
略
Lexical closures(詞法閉包)
一個(gè) 閉包 是一個(gè)方法對象卵贱,不管該對象在何處被調(diào)用滥沫, 該對象都可以訪問其作用域內(nèi) 的變量。
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
Testing functions for equality(測試函數(shù)是否相等)
強(qiáng)調(diào): 是判斷函數(shù)是否相等键俱,不是對象兰绣,這里不再說明。
Return values(返回值)
所有的函數(shù)都返回一個(gè)值编振。如果沒有指定返回值缀辩,則 默認(rèn)把語句 return null;
作為函數(shù)的最后一個(gè)語句執(zhí)行。
7、Operators(操作符)
Arithmetic operators(算術(shù)操作符)
assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // Result is a double
assert(5 ~/ 2 == 2); // Result is an integer
assert(5 % 2 == 1); // Remainder
print('5/2 = ${5~/2} r ${5%2}'); // 5/2 = 2 r 1
Equality and relational operators(相等相關(guān)的操作符)
assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);
Type test operators(類型判定操作符)
if (emp is Person) { // Type check
emp.firstName = 'Bob';
}
(emp as Person).firstName = 'Bob';
Assignment operators(賦值操作符)
a = value; // 給 a 變量賦值
b ??= value; // 如果 b 是 null臀玄,則賦值給 b瓢阴;
// 如果不是 null,則 b 的值保持不變
Logical operators(邏輯操作符)
略
Bitwise and shift operators(位和移位操作符)
略
Conditional expressions(條件表達(dá)式)
var finalStatus = m.isFinal ? 'final' : 'not final';
Cascade notation (..)(級聯(lián)操作符)
querySelector('#button') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
Other operators(其他操作符)
8健无、Control flow statements(流程控制語句)
可以使用下面的語句來控制 Dart 代碼的流程:
- if and else
- for loops
- while and do-while loops
- break and continue
- switch and case
- assert
var callbacks = [];
for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());
candidates.forEach((candidate) => candidate.interview());
9荣恐、Exceptions(異常)
Throw Catch Finally
distanceTo(Point other) =>
throw new UnimplementedError();
對于可以拋出多種類型異常的代碼,你可以指定 多個(gè)捕獲語句累贤。每個(gè)語句分別對應(yīng)一個(gè)異常類型叠穆, 如果捕獲語句沒有指定異常類型,則 該可以捕獲任何異常類型:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e');
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}
如之前代碼所示臼膏,你可以使用on 或者 catch 來聲明捕獲語句硼被,也可以 同時(shí)使用。使用 on 來指定異常類型渗磅,使用 catch 來 捕獲異常對象祷嘶。
try {
breedMoreLlamas();
} catch(e) {
print('Error: $e'); // Handle the exception first.
} finally {
cleanLlamaStalls(); // Then clean up.
}
10、Classes
Instance variables
略
Constructors
class Point {
num x;
num y;
// Syntactic sugar for setting x and y
// before the constructor body runs.
Point(this.x, this.y);
}
Default constructors(默認(rèn)構(gòu)造函數(shù))
如果你沒有定義構(gòu)造函數(shù)夺溢,則會(huì)有個(gè)默認(rèn)構(gòu)造函數(shù)。 默認(rèn)構(gòu)造函數(shù)沒有參數(shù)烛谊,并且會(huì)調(diào)用超類的 沒有參數(shù)的構(gòu)造函數(shù)风响。
Constructors aren’t inherited(構(gòu)造函數(shù)不會(huì)繼承)
子類不會(huì)繼承超類的構(gòu)造函數(shù)。 子類如果沒有定義構(gòu)造函數(shù)丹禀,則只有一個(gè)默認(rèn)構(gòu)造函數(shù) (沒有名字沒有參數(shù))状勤。
Named constructors(命名構(gòu)造函數(shù))
使用命名構(gòu)造函數(shù)可以為一個(gè)類實(shí)現(xiàn)多個(gè)構(gòu)造函數(shù), 或者使用命名構(gòu)造函數(shù)來更清晰的表明你的意圖:
class Point {
num x;
num y;
Point(this.x, this.y);
// Named constructor
Point.fromJson(Map json) {
x = json['x'];
y = json['y'];
}
}
-
Invoking a non-default superclass constructor(調(diào)用超類構(gòu)造函數(shù))
構(gòu)造函數(shù)執(zhí)行順序:
initializer list(初始化參數(shù)列表)
superclass’s no-arg constructor(超類的無名構(gòu)造函數(shù))
main class’s no-arg constructor(主類的無名構(gòu)造函數(shù))
class Person {
String firstName;
Person.fromJson(Map data) {
print('in Person');
}
}
class Employee extends Person {
// Person does not have a default constructor;
// you must call super.fromJson(data).
Employee.fromJson(Map data) : super.fromJson(data) {
print('in Employee');
}
}
main() {
var emp = new Employee.fromJson({});
// Prints:
// in Person
// in Employee
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
(emp as Person).firstName = 'Bob';
}
Initializer list(初始化列表)
在構(gòu)造函數(shù)體執(zhí)行之前除了可以調(diào)用超類構(gòu)造函數(shù)之外双泪,還可以 初始化實(shí)例參數(shù)持搜。 使用逗號分隔初始化表達(dá)式。
import 'dart:math';
class Point {
final num x;
final num y;
final num distanceFromOrigin;
Point(x, y)
: x = x,
y = y,
distanceFromOrigin = sqrt(x * x + y * y);
}
main() {
var p = new Point(2, 3);
print(p.distanceFromOrigin);
}
Redirecting constructors(重定向構(gòu)造函數(shù))
class Point {
num x;
num y;
// The main constructor for this class.
Point(this.x, this.y);
// Delegates to the main constructor.
Point.alongXAxis(num x) : this(x, 0);
}
Constant constructors(常量構(gòu)造函數(shù))
class ImmutablePoint {
final num x;
final num y;
const ImmutablePoint(this.x, this.y);
static final ImmutablePoint origin =
const ImmutablePoint(0, 0);
}
Factory constructors(工廠方法構(gòu)造函數(shù))
class Logger {
final String name;
bool mute = false;
// _cache is library-private, thanks to the _ in front
// of its name.
static final Map<String, Logger> _cache =
<String, Logger>{};
factory Logger(String name) {
if (_cache.containsKey(name)) {
return _cache[name];
} else {
final logger = new Logger._internal(name);
_cache[name] = logger;
return logger;
}
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) {
print(msg);
}
}
}
var logger = new Logger('UI');
logger.log('Button clicked');
Methods(函數(shù))
-
Instance methods(實(shí)例函數(shù))
略
-
Getters and setters
略
-
Abstract methods(抽象函數(shù))
略
-
Overridable operators(可覆寫的操作符)
class Vector {
final int x;
final int y;
const Vector(this.x, this.y);
/// Overrides + (a + b).
Vector operator +(Vector v) {
return new Vector(x + v.x, y + v.y);
}
/// Overrides - (a - b).
Vector operator -(Vector v) {
return new Vector(x - v.x, y - v.y);
}
}
main() {
final v = new Vector(2, 3);
final w = new Vector(2, 2);
// v == (2, 3)
assert(v.x == 2 && v.y == 3);
// v + w == (4, 5)
assert((v + w).x == 4 && (v + w).y == 5);
// v - w == (0, 1)
assert((v - w).x == 0 && (v - w).y == 1);
}
Abstract classes(抽象類)
略
Implicit interfaces(隱式接口)
每個(gè)類都隱式的定義了一個(gè)包含所有實(shí)例成員的接口焙矛, 并且這個(gè)類實(shí)現(xiàn)了這個(gè)接口葫盼。如果你想 創(chuàng)建類 A 來支持 類 B 的 api,而不想繼承 B 的實(shí)現(xiàn)村斟, 則類 A 應(yīng)該實(shí)現(xiàn) B 的接口贫导。
一個(gè)類可以通過 implements 關(guān)鍵字來實(shí)現(xiàn)一個(gè)或者多個(gè)接口, 并實(shí)現(xiàn)每個(gè)接口定義的 API蟆盹。 例如:
// A person. The implicit interface contains greet().
class Person {
// In the interface, but visible only in this library.
final _name;
// Not in the interface, since this is a constructor.
Person(this._name);
// In the interface.
String greet(who) => 'Hello, $who. I am $_name.';
}
// An implementation of the Person interface.
class Imposter implements Person {
// We have to define this, but we don't use it.
final _name = "";
String greet(who) => 'Hi $who. Do you know who I am?';
}
greetBob(Person person) => person.greet('bob');
main() {
print(greetBob(new Person('kathy')));
print(greetBob(new Imposter()));
}
Extending a class(擴(kuò)展類)
略
Enumerated types(枚舉類型)
略
Adding features to a class: mixins(為類添加新的功能)
Mixins 是一種在多類繼承中重用 一個(gè)類代碼的方法孩灯。
使用 with 關(guān)鍵字后面為一個(gè)或者多個(gè) mixin 名字來使用 mixin。 下面是示例顯示了如何使用 mixin:
class Musician extends Performer with Musical {
// ...
}
class Maestro extends Person
with Musical, Aggressive, Demented {
Maestro(String maestroName) {
name = maestroName;
canConduct = true;
}
}
定義一個(gè)類繼承 Object逾滥,該類沒有構(gòu)造函數(shù)峰档, 不能調(diào)用 super ,則該類就是一個(gè) mixin。例如:
abstract class 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');
}
}
}
Class variables and methods(類變量和函數(shù))
使用 static 關(guān)鍵字來實(shí)現(xiàn)類級別的變量和函數(shù)讥巡。
Static variables(靜態(tài)變量)
Static methods(靜態(tài)函數(shù))
11掀亩、Generics(泛型)
Generic collections and the types they contain
Dart 的泛型類型是固化的,在運(yùn)行時(shí)有也 可以判斷具體的類型尚卫。例如在運(yùn)行時(shí)(甚至是成產(chǎn)模式) 也可以檢測集合里面的對象類型:
var names = new List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
print(names is List<String>); // true
Using generic methods(使用泛型函數(shù))
一開始归榕,泛型只能在 Dart 類中使用。 新的語法也支持在函數(shù)和方法上使用泛型了吱涉。
T first<T>(List<T> ts) {
// ...Do some initial work or error checking, then...
T tmp ?= ts[0];
// ...Do some additional checking or processing...
return tmp;
}
12刹泄、Libraries and visibility(庫和可見性)
使用 import 和 library 指令可以幫助你創(chuàng)建 模塊化的可分享的代碼。庫不僅僅提供 API怎爵, 還是一個(gè)私有單元:以下劃線 (_) 開頭的標(biāo)識(shí)符只有在庫 內(nèi)部可見特石。每個(gè) Dart app 都是一個(gè)庫, 即使沒有使用 library 命令也是一個(gè)庫鳖链。
Using libraries(使用庫)
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// ...
Element element1 = new Element(); // Uses Element from lib1.
lib2.Element element2 = new lib2.Element(); // Uses Element from lib2.
Importing only part of a library(導(dǎo)入庫的一部分)
// Import only foo.
import 'package:lib1/lib1.dart' show foo;
// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;
Lazily loading a library(延遲載入庫)
要延遲加載一個(gè)庫姆蘸,需要先使用 deferred as 來 導(dǎo)入:
import 'package:deferred/hello.dart' deferred as hello;
當(dāng)需要使用的時(shí)候,使用庫標(biāo)識(shí)符調(diào)用 loadLibrary() 函數(shù)來加載庫:
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
在一個(gè)庫上你可以多次調(diào)用 loadLibrary()
函數(shù)芙委。 但是該庫只是載入一次逞敷。
使用延遲加載庫的時(shí)候,請注意一下問題:
- 延遲加載庫的常量在導(dǎo)入的時(shí)候是不可用的灌侣。 只有當(dāng)庫加載完畢的時(shí)候推捐,庫中常量才可以使用。
- 在導(dǎo)入文件的時(shí)候無法使用延遲庫中的類型侧啼。 如果你需要使用類型牛柒,則考慮把接口類型移動(dòng)到另外一個(gè)庫中, 讓兩個(gè)庫都分別導(dǎo)入這個(gè)接口庫痊乾。
- Dart 隱含的把
loadLibrary()
函數(shù)導(dǎo)入到使用deferred as *的命名空間*
中皮壁。loadLibrary()
方法返回一個(gè) Future。
Implementing libraries(實(shí)現(xiàn)庫)
13哪审、Asynchrony support(異步支持)
checkVersion() async {
var version = await lookUpVersion();
if (version == expectedVersion) {
// Do something.
} else {
// Do something else.
}
}
14蛾魄、Callable classes(可調(diào)用的類)
如果 Dart 類實(shí)現(xiàn)了 call() 函數(shù)則 可以當(dāng)做方法來調(diào)用。
在下面的示例中湿滓,WannabeFunction 類定義了一個(gè) call() 方法畏腕,該方法有三個(gè)字符串參數(shù),并且返回三個(gè)字符串 串聯(lián)起來的結(jié)果茉稠。
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');
}
15描馅、Isolates
略
16、Typedefs
在 Dart 語言中而线,方法也是對象铭污。 使用 typedef, 或者 function-type alias 來為方法類型命名恋日, 然后可以使用命名的方法。 當(dāng)把方法類型賦值給一個(gè)變量的時(shí)候嘹狞,typedef 保留類型信息岂膳。
typedef int Compare(Object a, Object b);
class SortedCollection {
Compare compare;
SortedCollection(this.compare);
}
// Initial, broken implementation.
int sort(Object a, Object b) => 0;
main() {
SortedCollection coll = new SortedCollection(sort);
assert(coll.compare is Function);
assert(coll.compare is Compare);
}
由于 typedefs 只是別名,他們還提供了一種 判斷任意 function 的類型的方法磅网。例如:
typedef int Compare(int a, int b);
int sort(int a, int b) => a - b;
main() {
assert(sort is Compare); // True!
}
17谈截、Metadata(元數(shù)據(jù))
使用元數(shù)據(jù)給你的代碼添加其他額外信息。 元數(shù)據(jù)注解是以 @ 字符開頭涧偷,后面是一個(gè)編譯時(shí) 常量(例如 deprecated)或者 調(diào)用一個(gè)常量構(gòu)造函數(shù)簸喂。
有三個(gè)注解所有的 Dart 代碼都可以使用: @deprecated、 @override燎潮、 和 @proxy喻鳄。
定義自己的元數(shù)據(jù)注解:
library todo;
class todo {
final String who;
final String what;
const todo(this.who, this.what);
}
使用 @todo 注解的示例:
import 'todo.dart';
@todo('seth', 'make this do something')
void doSomething() {
print('do something');
}
元數(shù)據(jù)可以在 library、 class确封、 typedef除呵、 type parameter、 constructor爪喘、 factory颜曾、 function、 field秉剑、 parameter泛豪、或者 variable 聲明之前使用,也可以在 import 或者 export 指令之前使用秃症。 使用反射可以在運(yùn)行時(shí)獲取元數(shù)據(jù) 信息。
18吕粹、Comments(注釋)
Single-line comments
Multi-line comments
Documentation comments
/// 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) {
// ...
}
}
19种柑、學(xué)習(xí)資料
對Dart感興趣的同學(xué)請查看 Dart官方文檔,進(jìn)行學(xué)習(xí)和參考匹耕。