1、dart不同於JavaScript的地方是,Dart將所有不爲True的值視作False。
2、如果正在重申的變量是可重申的,你可以使用 forEach()方法。如果你不需要知道重申計數器的值,使用forEach()是一個很好的選擇:
candidates.forEach((candidate) =>candidate.interview());
3、可重申的類例如Lish以及Set也支持for-in形式的 iteration:
var collection = [0,1,2];
for(var x in collection){
printf(x);
}
4、
if (emp is Person) { // Type check
emp.firstName = 'Bob';
}
你也可以通過as
來簡化代碼:
(emp as Person).firstName = 'Bob';
注意:上面兩段代碼並不相等。如果
emp
的值爲 null 或者不是 Person 的一個對象,第一段代碼不會做任何事情,第二段代碼將會報錯 。
5、assert
//確保這個變量不爲空值.
assert(text != null);
//確保這個變量小於100.
assert(number < 100);
//確保它是一個https協議類型的URL.
assert(urlString.startsWith(‘https’));
提示:Assert語句僅僅只能在調試模式下使用,在生產模式下沒有任何作用。
6、try { } on 異常類型 {} catch {} finally{}
try {
breedMoreLlamas();
} on OutOfLlamasException {
// 一個具體異常
buyMoreLlamas();
} on Exception catch (e) {
// 任意一個異常
print('Unknown exception: $e');
} catch (e) {
// 非具體類型
print('Something really unknown: $e');
}
像上面展示的代碼一樣,你可以用 on
或者 catch
,或者兩者都用。當你需要指定異常類型的時候用on
,當你的異常處理者需要異常對象時用catch
。
爲了確保不論是否拋出異常,代碼都正常運行,請使用 finally
子句。如果沒有 catch
匹配子句的異常, finally
子句運行以後異常將被傳播:
try {
breedMoreLlamas();
} finally {
// 即使拋出一個異常時也會進行清理
cleanLlamaStalls();
}
在匹配了所有 catch
之後,子句 finally
運行了。
try {
breedMoreLlamas();
} catch(e) {
print('Error: $e'); // 先處理異常
} finally {
cleanLlamaStalls(); // 然後清理
}
7、
Dart 是一種面嚮對象語言,包含類和基於 mixin 的繼承兩部分。每個對象是一個類的實例,並且 Object 是所有類的父類。基於 mixin 的繼承指的是每個類(除了 Object )都只有一個父類,類體還可以在多個類繼承中被重用。
要創建一個對象,你可以使用 new
關鍵詞並在其後跟上一個構造函數。構造函數可以寫成類名
,或者類名.標識符
形式。
實例變量
這裏是你如何聲明實例變量:
class Point {
num x; // 聲明實例變量 x ,默認值爲 null 。
num y; // 聲明實例變量 y ,默認值爲 null 。
num z = 0; // 聲明實例變量 z ,初始化爲 0 。
}
所有未初始化的實例變量的值爲 null
。
所有的實例變量會自動生成一個隱式的 getter 方法。 Non-final 實例變量也會自動生成一個隱式的 setter 方法。
8、默認構造函數
如果你不聲明一個構造函數,系統會提供默認構造函數。默認構造函數沒有參數,它將調用父類的無參數構造函數。
構造函數不能繼承
子類不繼承父類的構造函數。子類只有默認構造函數。(無參數,沒有名字的構造函數)。
命名構造函數
使用命名構造函數可以爲一個類聲明多個構造函
class Point {
num x;
num y;
Point(this.x, this.y);
// 命名構造函數
Point.fromJson(Map json) {
x = json['x'];
y = json['y'];
}
}
數,或者說是提供額外的聲明
記住,構造函數不能繼承,這意味着子類不會繼承父類的構造函數。如果你希望子類在創建之後能夠擁有在父類中聲明的命名構造函數,你就必須在子類中實現該構造函數。
9、調用非默認的父類的構造函數
默認情況下,在子類的構造函數將會調用父類的無參數構造函數。如果父類沒有構造函數,則必須手動調用父類的構造函數中的一個。在冒號(:)之後、構造函數之前指定父類的構造函數(如果有的話)。
class Person {
Person.fromJson(Map data) {
print('in Person');
}
}
class Employee extends Person {
// Person 沒有默認構造函數;
// 你必須調用 super.fromJson(data).
Employee.fromJson(Map data) : super.fromJson(data) {
print('in Employee');
}
}
main() {
var emp = new Employee.fromJson({});
// Prints:
// in Person
// in Employee
}
在調用父類構造函數前會檢測參數,這個參數可以是一個表達式,如函數調用:
class Employee extends Person {
// ...
Employee() : super.fromJson(findDefaultData());
}
警告:父類構造函數的參數不能訪問 this
。例如,參數可調用靜態方法但是不能調用實方法。
初始化列表
除了調用父類構造函數,你也可以在構造函數體運行之前初始化實例變量。用逗號隔開使其分別初始化。
class Point {
num x;
num y;
Point(this.x, this.y);
// 初始化列表在構造函數運行前設置實例變量。
Point.fromJson(Map jsonMap)
: x = jsonMap['x'],
y = jsonMap['y'] {
print('In Point.fromJson(): ($x, $y)');
}
}
警告:右手邊的初始化程序無法訪問 this
關鍵字。
靜態構造函數
如果你的類產生的對象永遠不會改變,你可以讓這些對象成爲編譯時常量。爲此,需要定義一個 const
構造函數並確保所有的實例變量都是 final
的。
class ImmutablePoint {
final num x;
final num y;
const ImmutablePoint(this.x, this.y);
static final ImmutablePoint origin =
const ImmutablePoint(0, 0);
}
工廠構造函數
當實現一個使用 factory
關鍵詞修飾的構造函數時,這個構造函數不必創建類的新實例。例如,工廠構造函數可能從緩存返回實例,或者它可能返回子類型的實例。 下面的示例演示一個工廠構造函數從緩存返回的對象:
class Logger {
final String name;
bool mute = false;
// _cache 是一個私有庫,幸好名字前有個 _ 。
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);
}
}
}
注:工廠構造函數不能用 this。
調用一個工廠構造函數,你需要使用 new
關鍵字:
var logger = new Logger('UI');
logger.log('Button clicked');
10、方法
方法就是爲對象提供行爲的函數。
你可以使用 @override
註釋來表明你重寫了一個成員。
class A {
@override
void noSuchMethod(Invocation mirror) {
// ...
}
}
如果你用 noSuchMethod()
實現每一個可能的 getter 方法,setter 方法和類的方法,那麼你可以使用 @proxy
標註來避免警告。