運算符在編程語言中也是很重要的一環,如果有其他語言基礎的話看這一節會很輕鬆,但是也要特別注意一些運算符,因爲它跟其他語言還是有點差別的。
在運算符表 中,運算符的優先級按先後排列,即第一行優先級最高,最後一行優先級最低,而同一行中,最左邊的優先級最高,最右邊的優先級最低。
描述 | 運算符 |
---|---|
一元后綴 | 表達式++ 表達式-- () [] . ?. |
一元前綴 | -表達式 !表達式 ~表達式 ++表達式 --表達式 |
乘除法 | * / % ~/ |
加減法 | + - |
位運算 | << >> >>> |
二進制與 | & |
二進制異或 | ^ |
二進制或 | | |
關係和類型測試 >= > <= < as is is!
相等判斷 == !=
邏輯與 &&
邏輯或 ||
空判斷 ??
條件表達式 表達式 1 ? 表達式 2 : 表達式 3
級聯 …
賦值 = *= /= += -= &= ^= 等等……
一旦你使用了運算符,就創建了表達式。
a++
a + b
a = b
a == b
c ? a : b
a is T
// 括號提高了可讀性。
if ((n % i == 0) && (d % i == 0)) ...
// 難以理解,但是與上面的代碼效果一樣。
if (n % i == 0 && d % i == 0) ...
算術運算符
Dart 支持常用的算術運算符:
描述 | 運算符 |
---|---|
+ | 表達式++ 表達式-- () [] . ?. |
– | 減 |
-表達式 | 一元負, 也可以作爲反轉(反轉表達式的符號) |
* | 乘 |
/ | 除 |
~/ | 除並取整 |
% | 取模 |
示例:
assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // 結果是一個浮點數
assert(5 ~/ 2 == 2); // 結果是一個整數
assert(5 % 2 == 1); // 取餘
assert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');
Dart 還支持自增自減操作。
++var
var = var + 1 (表達式的值爲 var + 1)
var++ var = var + 1 (表達式的值爲 var)
--var var = var – 1 (表達式的值爲 var – 1)
var-- var = var – 1 (表達式的值爲 var)
示例:
var a, b;
a = 0;
b = ++a; // 在 b 賦值前將 a 增加 1。
assert(a == b); // 1 == 1
a = 0;
b = a++; // 在 b 賦值後將 a 增加 1。
assert(a != b); // 1 != 0
a = 0;
b = --a; // 在 b 賦值前將 a 減少 1。
assert(a == b); // -1 == -1
a = 0;
b = a--; // 在 b 賦值後將 a 減少 1。
assert(a != b); // -1 != 0
關係運算符
== 相等
!= 不等
> 大於
< 小於
>= 大於等於
<= 小於等於
要判斷兩個對象 x 和 y 是否表示相同的事物使用 == 即可。
== 運算符的一些規則:
1.假設有變量 x 和 y,且 x 和 y 至少有一個爲 null,則當且僅當 x 和 y 均爲 null 時 x == y 纔會返回 true,否則只有一個爲 null 則返回 false。
2.x.==(y) 將會返回值,這裏不管有沒有 y,即 y 是可選的。也就是說 == 其實是 x 中的一個方法,並且可以被重寫。
下面的代碼給出了每一種關係運算符的示例:
assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);
類型判斷運算符
as //類型轉換(也用作指定類前綴))
is //如果對象是指定類型則返回 true
is! //如果對象是指定類型則返回 false
當且僅當 obj 實現了 T 的接口,obj is T 纔是 true。例如 obj is Object 總爲 true,因爲所有類都是 Object 的子類。
使用 as 操作符可以把對象轉換爲特定的類型。一般情況下可以將其當做 is 判定類型後調用所判定對象的函數的縮寫形式。假設有如下代碼:
if (emp is Person) {
// 類型檢查
emp.firstName = 'Bob';
}
你可以使用 as 運算符進行縮寫:
(emp as Person).firstName = 'Bob';
tips:上述兩種方式是有區別的:如果 emp 爲 null 或者不爲 Person 類型,則第一種方式最多隻是不執行條件內代碼,但是第二種方式則會拋出異常。
賦值運算符
可以使用 = 來賦值,同時也可以使用 ??= 來爲值爲 null 的變量賦值。
// 將 value 賦值給 a
a = value;
// 當且僅當 b 爲 null 時才賦值
b ??= value;
像 += 這樣的賦值運算符將算數運算符和賦值運算符組合在了一起。
= –= /= %= >>= ^=
+= *= ~/= <<= &= |=
下表解釋了符合運算符的原理:
場景 複合運算 等效表達式
假設有運算符 op: a op= b a = a op b
示例: a += b a = a + b
下面的例子展示瞭如何使用賦值以及複合賦值運算符:
var a = 2; // 使用 = 賦值
a *= 3; // 賦值並做乘法運算:a = a * 3
assert(a == 6);
邏輯運算符
使用邏輯運算符你可以反轉或組合布爾表達式。
運算符 描述
!!表達式 對錶達式結果取反(即將 true 變爲 false,false 變爲 true)
|| 邏輯或
&& 邏輯與
下面是使用邏輯表達式的示例:
if (!done && (col == 0 || col == 3)) {
// ...Do something...
}
按位和移位運算符
在 Dart 中,二進制位運算符可以操作二進制的某一位,但僅適用於整數。
運算符 描述
& 按位與
| 按位或
^ 按位異或
~表達式 按位取反
<< 左位移
>> 右位移
下面是使用按位和移位運算符的示例:
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); // 位右移
條件表達式
Dart 有兩個特殊的運算符可以用來替代 if-else 語句:
condition ? expr1 : expr2 //條件 ? 表達式 1 : 表達式 2:如果條件爲 true,執行表達式 1並返回執行結果,否則執行表達式 2 並返回執行結果。
expr1 ?? expr2表達式 1 ?? 表達式 2:如果表達式 1 爲非 null 則返回其值,否則執行表達式 2 並返回其值。
如果賦值是根據布爾表達式則考慮使用 ?:。
var visibility = isPublic ? 'public' : 'private';
如果賦值是根據判定是否爲 null 則考慮使用 ??。
String playerName(String name) => name ?? 'Guest';
上述示例還可以寫成至少下面兩種不同的形式,只是不夠簡潔:
// 相對使用 ?: 運算符來說稍微長了點。
String playerName(String name) => name != null ? name : 'Guest';
// 如果使用 if-else 則更長。
String playerName(String name) {
if (name != null) {
return name;
} else {
return 'Guest';
}
}
級聯運算符(…)
級聯運算符(…)可以讓你在同一個對象上連續調用多個對象的變量或方法。
比如下面的代碼:
querySelector('#confirm') // 獲取對象。
..text = 'Confirm' // 使用對象的成員。
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
第一個方法 querySelector 返回了一個 Selector 對象,後面的級聯操作符都是調用這個 Selector 對象的成員並忽略每個操作的返回值。
上面的代碼相當於:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
級聯運算符可以嵌套,例如:
final addressBook = (AddressBookBuilder()
..name = 'jenny'
..email = '[email protected]'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
在返回對象的函數中謹慎使用級聯操作符。例如,下面的代碼是錯誤的:
var sb = StringBuffer();
sb.write('foo')
..write('bar'); // 出錯:void 對象中沒有方法 write。
上述代碼中的 sb.write() 方法返回的是 void,返回值爲 void 的方法則不能使用級聯運算符。
tips:嚴格來說 … 級聯操作並非一個運算符而是 Dart 的特殊語法。結語:
最近在錄製視頻,到時候也會免費放在公衆號中供大家學習交流使用。如果對您有用請關注,如果文中有錯也歡迎指正。共同學習,共同進步。