Dart編程語言從基礎到進階7

運算符在編程語言中也是很重要的一環,如果有其他語言基礎的話看這一節會很輕鬆,但是也要特別注意一些運算符,因爲它跟其他語言還是有點差別的。

在運算符表 中,運算符的優先級按先後排列,即第一行優先級最高,最後一行優先級最低,而同一行中,最左邊的優先級最高,最右邊的優先級最低。

描述 運算符
一元后綴 表達式++ 表達式-- () [] . ?.
一元前綴 -表達式 !表達式 ~表達式 ++表達式 --表達式
乘除法 * / % ~/
加減法 + -
位運算 << >> >>>
二進制與 &
二進制異或 ^
二進制或 |

關係和類型測試 >= > <= < 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 的特殊語法。結語:

最近在錄製視頻,到時候也會免費放在公衆號中供大家學習交流使用。如果對您有用請關注,如果文中有錯也歡迎指正。共同學習,共同進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章