【Flutter 1-10】Flutter手把手教程Dart語(yǔ)言——運(yùn)算符

作者 | 弗拉德
來(lái)源 | 弗拉德(公眾號(hào):fulade_me)

運(yùn)算符

運(yùn)算符是一種告訴編譯器執(zhí)行特定的數(shù)學(xué)或邏輯操作的符號(hào)。Dart語(yǔ)言?xún)?nèi)置了豐富的運(yùn)算符,并提供了以下類(lèi)型的運(yùn)算符:算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、類(lèi)型判斷運(yùn)算符、賦值運(yùn)算符、邏輯運(yùn)算符、按位和移位運(yùn)算符、條件表達(dá)式、級(jí)聯(lián)運(yùn)算符以及其他運(yùn)算符。

算數(shù)運(yùn)算符

算數(shù)運(yùn)算符 描述
+
-
- 表達(dá)式 一元負(fù), 也可以作為反轉(zhuǎn)(反轉(zhuǎn)表達(dá)式的符號(hào))
*
/
~/ 除并取整
% 取模

示例:

assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // 結(jié)果是一個(gè)浮點(diǎn)數(shù)
assert(5 ~/ 2 == 2); // 結(jié)果是一個(gè)整數(shù)
assert(5 % 2 == 1); // 取余

assert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');

Dart 還支持自增自減運(yùn)算符:

自增自減運(yùn)算符 描述
++ var var = var + 1 (表達(dá)式的值為 var + 1)
var ++ var = var + 1 (表達(dá)式的值為 var)
-- var var = var – 1 (表達(dá)式的值為 var – 1)
var -- var = var – 1 (表達(dá)式的值為 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

關(guān)系運(yùn)算符

關(guān)系運(yùn)算符 描述
== 相等
!= 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于

要判斷兩個(gè)對(duì)象 x 和 y 是否表示相同的事物使用 == 即可。(在極少數(shù)情況下,可能需要使用 identical() 函數(shù)來(lái)確定兩個(gè)對(duì)象是否完全相同)。
下面是 == 運(yùn)算符的一些規(guī)則:

  1. 假設(shè)有變量 xy,且 xy 至少有一個(gè)為 null,則當(dāng)且僅當(dāng) xy 均為 null 時(shí) x == y 才會(huì)返回 true,否則只有一個(gè)為 null 則返回 false。

  2. x.==(y) 將會(huì)返回值,這里不管有沒(méi)有y,即 y 是可選的。也就是說(shuō) == 其實(shí)是 x 中的一個(gè)方法,并且可以被重寫(xiě)。

下面的代碼給出了每一種關(guān)系運(yùn)算符的示例:

assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);

類(lèi)型判斷運(yùn)算符

as、is、is! 運(yùn)算符是在運(yùn)行時(shí)判斷對(duì)象類(lèi)型的運(yùn)算符。

類(lèi)型判斷運(yùn)算符 描述
as 類(lèi)型轉(zhuǎn)換(也用作指定類(lèi)前綴))
is 如果對(duì)象是指定類(lèi)型則返回 true
is! 如果對(duì)象是指定類(lèi)型則返回 false

當(dāng)且僅當(dāng) obj對(duì)象 實(shí)現(xiàn)了 T 的接口,obj對(duì)象 is T 才是 true。例如 obj對(duì)象 is Object 總為 true,因?yàn)樗蓄?lèi)都是 Object 的子類(lèi)。

僅當(dāng)你確定這個(gè)對(duì)象是該類(lèi)型的時(shí)候,你才可以使用 as 操作符可以把對(duì)象轉(zhuǎn)換為特定的類(lèi)型。例如:

(emp as Person).firstName = 'Bob';

如果你不確定這個(gè)對(duì)象類(lèi)型是不是 T,請(qǐng)?jiān)谵D(zhuǎn)型前使用 is T 檢查類(lèi)型。

if (emp is Person) {
  // 類(lèi)型檢查
  emp.firstName = 'Bob';
}

你可以使用 as 運(yùn)算符進(jìn)行縮寫(xiě):

(emp as Person).firstName = 'Bob';

賦值運(yùn)算符

可以使用 = 來(lái)賦值,同時(shí)也可以使用 ??= 來(lái)為值為 null 的變量賦值。

// 將 value 賦值給 a (Assign value to a)
a = value;
// 當(dāng)且僅當(dāng) b 為 null 時(shí)才賦值
b ??= value;

+= 這樣的賦值運(yùn)算符將算數(shù)運(yùn)算符和賦值運(yùn)算符組合在了一起。

= –= /= %= >>= ^=
+= *= ~/= <<= &= =

下面的例子展示了如何使用賦值以及復(fù)合賦值運(yùn)算符:

a += b      //就 等同于 a = a + b
var a = 2; // 使用 = 賦值 (Assign using =)
a *= 3; // 賦值并做乘法運(yùn)算 Assign and multiply: a = a * 3
assert(a == 6);

邏輯運(yùn)算符

類(lèi)型判斷運(yùn)算符 描述
!表達(dá)式 對(duì)表達(dá)式結(jié)果取反(即將 true 變?yōu)?false,false 變?yōu)?true)
|| 邏輯或
&& 邏輯與

下面是使用邏輯表達(dá)式的示例:

if (!done && (col == 0 || col == 3)) {
  // ...Do something...
}

按位和移位運(yùn)算符

按位和移位運(yùn)算符 描述
& 按位與
| 按位或
^ 按位異或
~ 表達(dá)式 按位取反(即將 “0” 變?yōu)?“1”,“1” 變?yōu)?“0”)
<< 位左移
>> 位右移

下面是使用按位和移位運(yùn)算符的示例:

final value = 0x22;
final bitmask = 0x0f;
assert((value & bitmask) == 0x02); // 按位與 (AND)
assert((value & ~bitmask) == 0x20); // 取反后按位與 (AND NOT)
assert((value | bitmask) == 0x2f); // 按位或 (OR)
assert((value ^ bitmask) == 0x2d); // 按位異或 (XOR)
assert((value << 4) == 0x220); // 位左移 (Shift left)
assert((value >> 4) == 0x02); // 位右移 (Shift right)

條件表達(dá)式

條件 ? 表達(dá)式 1 : 表達(dá)式 2 :如果條件為 true,執(zhí)行表達(dá)式 1并返回執(zhí)行結(jié)果,否則執(zhí)行表達(dá)式 2 并返回執(zhí)行結(jié)果。
表達(dá)式 1 ?? 表達(dá)式 2:如果表達(dá)式 1 為非 null 則返回其值,否則執(zhí)行表達(dá)式 2 并返回其值。
如果賦值是根據(jù)布爾表達(dá)式則考慮使用 ?:

var visibility = isPublic ? 'public' : 'private';

如果賦值是根據(jù)判定是否為 null 則考慮使用 ??

String playerName(String name) => name ?? 'Guest';

上述示例還可以寫(xiě)成至少下面兩種不同的形式,只是不夠簡(jiǎn)潔:

// 相對(duì)使用 ?: 運(yùn)算符來(lái)說(shuō)稍微長(zhǎng)了點(diǎn)。(Slightly longer version uses ?: operator).
String playerName(String name) => name != null ? name : 'Guest';

// 如果使用 if-else 則更長(zhǎng)。
String playerName(String name) {
  if (name != null) {
    return name;
  } else {
    return 'Guest';
  }
}

級(jí)聯(lián)運(yùn)算符

級(jí)聯(lián)運(yùn)算符(..)可以讓你在同一個(gè)對(duì)象上連續(xù)調(diào)用多個(gè)對(duì)象的變量或方法。
比如下面的代碼:

querySelector('#confirm') // 獲取對(duì)象 (Get an object).
  ..text = 'Confirm' // 使用對(duì)象的成員 (Use its members).
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

第一個(gè)方法 querySelector 返回了一個(gè) Selector 對(duì)象,后面的級(jí)聯(lián)操作符都是調(diào)用這個(gè) Selector 對(duì)象的成員并忽略每個(gè)操作的返回值。

上面的代碼相當(dāng)于:

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

級(jí)聯(lián)運(yùn)算符可以嵌套,例如:

final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

在返回對(duì)象的函數(shù)中謹(jǐn)慎使用級(jí)聯(lián)操作符。例如,下面的代碼是錯(cuò)誤的:

var sb = StringBuffer();
sb.write('foo')
  ..write('bar'); // 出錯(cuò):void 對(duì)象中沒(méi)有方法 write (Error: method 'write' isn't defined for 'void').

上述代碼中的 sb.write() 方法返回的是 void,返回值為 void 的方法則不能使用級(jí)聯(lián)運(yùn)算符。

其他運(yùn)算符

大多數(shù)其它的運(yùn)算符,已經(jīng)在其它的示例中使用過(guò):

運(yùn)算符 名字 描述
() 使用方法 代表調(diào)用一個(gè)方法
[] 訪問(wèn) List 訪問(wèn) List 中特定位置的元素
. 訪問(wèn)成員 成員訪問(wèn)符
?. 條件訪問(wèn)成員 與上述成員訪問(wèn)符類(lèi)似,但是左邊的操作對(duì)象不能為 null,例如 foo?.bar,如果 foo 為 null 則返回 null ,否則返回 bar

更多關(guān)于 ., ?... 運(yùn)算符介紹,會(huì)在下一章Flutter手把手教程Dart語(yǔ)言——類(lèi)中講解.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容