一、Operators(操作符)
注:expr為表達式,操作符的優(yōu)先級在下表中自上而下的順序由高到低。
| 描述 | 操作符 |
|---|---|
| 一元后綴 | expr++ expr-- () [] . ?.
|
| 一元前綴 | -expr !expr ~expr ++expr --expr |
| 乘法類型 |
* / % ~/
|
| 加法類型 |
+ -
|
移動位運算 |
<< >>
|
與位運算 |
& |
異或位運算 |
^ |
或位運算 |
| |
| 關(guān)系和類型測試 |
>= > <= < as is is!
|
| 等式 |
== !=
|
| 邏輯與 | && |
| 邏輯或 | || |
| 空值判斷 | ?? |
| 條件 | expr1 ? expr2 : expr3 |
| 級聯(lián) | .. |
| 賦值 |
= *= /= ~/= %= += -= <<= >>= &= ^= |= ??=
|
1.1. Arithmetic operators(算術(shù)操作符)
| 操作符 | 解釋 |
|---|---|
| + | 加號 |
| - | 減號 |
-expr |
負(fù)號 |
| * | 乘號 |
| / | 除號 |
| ~/ | 除號,但是返回值為整數(shù) |
| % | 取模 |
var a = 20 ~/ 5;
var b = 20 ~/ 3;
var c = 20 ~/ 3.0;
/*
Dart是強語法類型,報錯:A value of type 'double'
cant't be assigned to a variable of type 'int'.
*/
int d = 20 / 3;
/*
可以調(diào)用toInt()強制類型轉(zhuǎn)換,但是不建議使用,編譯器會提示:
The operator x ~/ y is more efficient than (x / y).toInt().
*/
int e = (20 / 3).toInt();
print(a); // 4
print(b); // 6
print(c); // 6
print(e); // 6
Dart 還支持遞增、遞減前綴 和后綴操作:
| 操作符 | 解釋 |
|---|---|
++var |
var = var + 1 (expression value is var + 1) |
var++ |
var = var + 1 (expression value is var) |
--var |
var = var – 1 (expression value is var – 1) |
var-- |
var = var – 1 (expression value is var) |
1.2.Equality and relational operators(相等相關(guān)的操作符)
注:要測試兩個對象代表的是否為同樣的內(nèi)容,使用
==操作符。(在某些情況下,你需要知道兩個對象是否是同一個對象, 使用identical()方法。)
| 操作符 | 解釋 |
|---|---|
== |
相等 |
!= |
不等 |
> |
大于 |
< |
小于 |
>= |
大于等于 |
<= |
小于等于 |
List list1 = List();
List list2 = List();
Map map = Map();
Object a = List();
Object b = List();
int c = 2;
int d = 6;
int h = 2;
print(identical(list1, map)); // false
print(identical(list1, list2)); // false
print(identical(c, d)); // false
print(identical(a, b)); // false
print(identical(c, h)); // true
// 為什么 c和h是同一個對象?因為HashCode相同!
print(identityHashCode(c)); // 2
print(identityHashCode(h)); // 2
1.3. Type test operators(類型判定操作符)
as、is、和is! 操作符是在運行時判定對象 類型的操作符:
| 操作符 | 解釋 |
|---|---|
| as | 類型轉(zhuǎn)換 |
| is | 如果對象是指定的類型返回 True |
| is! | 如果對象是指定的類型返回 False |
只有當(dāng) obj 實現(xiàn)了 T 的接口, obj is T 才是 true。例如 obj is Object 總是 true。
使用 as 操作符把對象轉(zhuǎn)換為特定的類型。 一般情況下,你可以把它當(dāng)做用 is 判定類型然后調(diào)用所判定對象的函數(shù)的縮寫形式。例如下面的示例:
/ *
注意: 下面這兩個代碼效果是有區(qū)別的。如果 emp 是 null 或者不是 Person 類型,
則使用 is 則不會執(zhí)行條件里面的代碼,而使用 as 則會拋出一個異常。
*/
if (emp is Person) { // 類型檢查
emp.firstName = 'Bob';
}
// 使用 as 操作符可以簡化上面的代碼:
(emp as Person).firstName = 'Bob';
1.4. Assignment operators(賦值操作符)
使用= 操作符來賦值。 但是還有一個 ??= 操作符用來指定 值為 null 的變量的值。
| 操作符 | 操作符 | 操作符 | 操作符 | 操作符 | 操作符 |
|---|---|---|---|---|---|
= |
–= |
/= |
%= |
>>= |
^= |
+= |
*= |
~/= |
<<= |
&= |
|= |
下面是復(fù)合賦值操作符工作原理解釋:
| 復(fù)合賦值操作符 | 相等的表達式 | |
|---|---|---|
| 對于 操作符 op: | a op= b |
a = a op b |
| 示例: | a += b |
a = a + b |
int a = 7; // 給 a 變量賦值
/*
如果 b 是 null,則賦值給 b;如果不是 null,則 b 的值保持不變
*/
int b = 1;
b ??= 9;
// 使用 ??= 前,變量c一定要先聲明或者聲明且賦值的,否則編譯器報錯
int c ??= 9;
1.5.Logical operators(邏輯操作符)
| 操作符 | 解釋 |
|---|---|
!expr |
對表達式結(jié)果取反(true 變?yōu)?false ,false 變?yōu)?true) |
|| |
邏輯或 |
&& |
邏輯與 |
1.6.Bitwise and shift operators(位和移位操作符)
| 操作符 | 解釋 |
|---|---|
& |
AND(與) |
| |
OR(或) |
^ |
XOR(異或) |
~expr |
Unary bitwise complement (0s become 1s; 1s become 0s)(一元位補碼( 0s變?yōu)?s;1s變?yōu)?s )) |
<< |
Shift left(左移) |
>> |
Shift right(右移) |
final value = 0x22;
final bitmask = 0x0f;
assert((value & bitmask) == 0x02); // 與
assert((value & ~bitmask) == 0x20); // 與非
assert((value | bitmask) == 0x2f); // 或
assert((value ^ bitmask) == 0x2d); // 異或
assert((value << 4) == 0x220); // 左移
assert((value >> 4) == 0x02); // 右移
1.7.Conditional expressions(條件表達式)
Dart有兩個運算符,可讓您簡明地評估可能需要if-else語句的表達式:
condition ? expr1 : expr2
如果條件為真,返回expr1,否則返回expr2
expr1 ?? expr2
如果expr1為非空,則返回其值;否則,計算并返回expr2的值。
- 如果你需要根據(jù)布爾表達式賦值時,考慮使用
?:
var isHidden = (3 > 2) ? true : false;
- 如果布爾表達式測試為空,考慮使用
??
String studentName(String name) => msg ?? 'Tom';
// 非常長的使用if - else語句的版本
String studentName(String name) {
if (name != null) {
return name;
} else {
return 'Tom';
}
1.8.Cascade notation (..)(級聯(lián)操作符)
級聯(lián)操作符 (..) 可以在同一個對象上連續(xù)調(diào)用多個函數(shù)以及訪問成員變量。 使用級聯(lián)操作符可以避免創(chuàng)建臨時變量,并且寫出來的代碼看起來更加流暢:
querySelector('#confirm') // 獲取一個對象
..text = 'Confirm' // 使用它的成員
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
第一個方法 querySelector() 返回了一個 selector 對象。 后面的級聯(lián)操作符都是調(diào)用這個對象的成員, 并忽略每個操作所返回的值。
上面的代碼和下面的代碼功能一樣:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
級聯(lián)調(diào)用也可以嵌套:
final addressBook = (AddressBookBuilder()
..name = 'jenny'
..email = 'jenny@example.com'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
無法在 返回值為void 上使用級聯(lián)操作符:
var sb = StringBuffer();
// sb.write() 函數(shù)返回一個 void, 無法在 void 上使用級聯(lián)操作符。
sb.write('foo')
..write('bar'); // 錯誤:沒有為“void”定義的方法“write”。
注意: 嚴(yán)格來說, 兩個點的級聯(lián)語法不是一個操作符。 只是一個 Dart 特殊語法。
1.9.Other operators(其他操作符)
| 操作符 | 名稱 | 含義 |
|---|---|---|
() |
使用方法 | 代表調(diào)用一個方法 |
[] |
訪問List
|
訪問List 中特定位置的元素 |
. |
訪問 Member | 訪問元素,例如 foo.bar 代表訪問 foo 的 bar 成員 |
?. |
條件成員訪問 | 和 . 類似,但是左邊的操作對象可以為 null,例如 foo?.bar 如果foo 為 null 則返回 null,否則返回 bar 成員 |
var str1 = "hello world";
var str2 = null;
print(str1?.length); // 11
print(str2?.length); // null,此語法類似swift語言中的Optional(?.)
print(str2.length); // 報錯
二、代碼注釋
Dart 支持單行注釋、多行注釋和 文檔注釋。
- 單行注釋以
//開始。//后面的一行內(nèi)容 為 Dart 代碼注釋。
// 打印 ff
print('ff');
- 多行注釋以
/*開始,*/結(jié)尾。 多行注釋 可以 嵌套。
/*
* This is a lot of work. Consider raising chickens.
Llama larry = new Llama();
larry.feed();
larry.exercise();
larry.clean();
*/
- TODO注釋
// TODO: refactor into an AbstractLlamaGreetingFactory?
print('Welcome to my Llama farm!');
- 文檔注釋
文檔注釋可以使用 /// 開始, 也可以使用 /** 開始 并以 */結(jié)束。
在文檔注釋內(nèi), Dart 編譯器忽略除了[]以外的內(nèi)容。 使用[]引用 classes、 methods、 fields、 top-level variables、 functions、 和 parameters。[]里面的名字使用 當(dāng)前注釋出現(xiàn)地方的語法范圍查找對應(yīng)的成員(在簡書markdown中,[]中的內(nèi)容無法高亮顯示和點擊查詢跳轉(zhuǎn),有些遺憾,但在例如:WebStorm、裝有支持Dart IDE的插件開發(fā)工具中可以體現(xiàn))。
class Food {
}
class Activity {
}
/// 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) {
// ...
}