动态

详情 返回 返回

Flutter/Dart第12天:Dart控制流詳解 - 动态 详情

Dart控制流主要由循環分支組成:

  • Dart官方文檔-循環:https://dart.dev/language/loops
  • Dart官方文檔-分支:https://dart.dev/language/branches

重要説明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。

循環

Dart可通過循環來控制邏輯流,它支持3種語句:for循環,whiledo while循環,breakcontinue

同時,也可以通過非循環來控制邏輯流,包括:分支(如:ifswitch)和異常(trycatchthrow)等

for循環

for循環可以使用在迭代中,標準用法如下代碼樣例:

var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
  message.write('!');
}

for-in循環常用於無需關注迭代的索引,如下代碼樣例,包含了閉包列表和迭代:

var callbacks = [];
for (var i = 0; i < 2; i++) {
  callbacks.add(() => print(i));
}

for (final c in callbacks) {
  c();
}
// 解構:01

同樣的,for-in循環還可以使用對象模式(Pattern模式詳解:https://ntopic.cn/p/2023100501),解構迭代的元素:

for (final Candidate(:name, :yearsExperience) in candidates) {
  print('$name has $yearsExperience of experience.');
}

對於迭代類型(Dart可迭代集合詳解:https://ntopic.cn/p/2023092701),forEach()方法也可以實現循環:

var collection = [1, 2, 3];
collection.forEach(print); // 1 2 3

while和do while循環

while循環do while循環最大的區別:while先檢測循環條件,然後執行循環邏輯;do while默認先執行1次循環邏輯,然後檢測循環條件,以決定後續是否繼續執行循環邏輯。

while (!isDone()) {
  doSomething();
}

do {
  printLine();
} while (!atEndOfPage());

break和continue循環控制

breakcontinue在循環中的最大區別:break中斷整個循環,而continue中斷當前循環的後續邏輯

while (true) {
  if (shutDownRequested()) break;
  processIncomingRequests();
}

for (int i = 0; i < candidates.length; i++) {
  var candidate = candidates[i];
  if (candidate.yearsExperience < 5) {
    continue;
  }
  candidate.interview();
}

// 若`candidates`是可迭代列表,則上面的邏輯可改寫如下:
candidates
    .where((c) => c.yearsExperience >= 5)
    .forEach((c) => c.interview());

分支

Dart也可通過分支來控制邏輯流:if語句和元素,if-case語句和元素,switch語句和switch表達式等。

同樣的,我們也可以通過其他方式來控制邏輯流:如循環(就是本文的第1節)和異常(trycatchthrow)等

if/else分支

if語句可以有else可選項子句,if後面的括號中的表達式計算值必須是boolean類型,如下代碼樣例:

if (isRaining()) {
  you.bringRainCoat();
} else if (isSnowing()) {
  you.wearJacket();
} else {
  car.putTopDown();
}

if-case模式

Dart中if語句後的case子句可以帶一個模式(Pattern模式詳解:https://ntopic.cn/p/2023100501):

if (pair case [int x, int y]) return Point(x, y);

上訴代碼樣例中,列表模式[int x, int y]首先匹配pair值,並且把列表第1和第2個int類型的元素解構並賦值給了xy變量。

如果模式未能成功匹配,則需要進入else分支:

if (pair case [int x, int y]) {
  print('Was coordinate array $x,$y');
} else {
  throw FormatException('Invalid coordinates.');
}

switch語句和switch表達式

switch語句後面可以有多個case子句,每一個case子句都可以是一個模式(Pattern模式詳解:https://ntopic.cn/p/2023100501)。

當沒有case子句匹配時,就會執行default子句或者_通配符子句:

switch (command) {
  case 'OPEN':
    executeOpen();
    continue newCase; // 繼續執行

  case 'DENIED':
  case 'CLOSED':
    executeClosed(); // `DENIED`和`CLOSED`均會執行

  newCase:
  case 'PENDING':
    executeNowClosed(); // `OPEN`和`PENDING`均會執行
}

在switch語句中,還可以使用模式,有如下幾種用法:

var x = switch (y) { ... };

print(switch (x) { ... });

return switch (x) { ... };

switch表達式可以重寫switch語句,如下為switch語句的代碼樣例:

// `slash`, `star`, `comma`, `semicolon`等,需要是常量
switch (charCode) {
  case slash || star || plus || minus: // `邏輯或`模式
    token = operator(charCode);
  case comma || semicolon: // `邏輯或`模式
    token = punctuation(charCode);
  case >= digit0 && <= digit9: // `關係`和`邏輯與`模式
    token = number();
  default:
    throw FormatException('Invalid');
}

上訴代碼樣例,可以使用switch表達式重寫如下:

token = switch (charCode) {
  slash || star || plus || minus => operator(charCode),
  comma || semicolon => punctuation(charCode),
  >= digit0 && <= digit9 => number(),
  _ => throw FormatException('Invalid')
};

switch表達式不同於switch語句的語法,包括以下幾個方面:

  • Case可選項無需使用case開頭。
  • Case可選項的邏輯是一個表達式,而不是一系列的語句。
  • Case可選項都必須有邏輯,空可選性不代表隱性失敗。
  • Case可選項模式,邏輯使用=>分割。
  • 多個Case可選項之間,使用,分割。
  • 默認可選項,只能使用_

Switch還可以使用在窮舉檢測中,就是所有的值都有對應的可選項被處理,以避免引發編譯錯誤。默認可選項(default_)涵蓋了所有其他情況,因此它可以保障窮舉性。

case-when子句

case-when子句:case子句後面增加when子句。case-when子句可以用在if-caseswitch語句switch表達式中。

switch (pair) {
  case (int a, int b) when a > b:
    print('First element greater');
  case (int a, int b):
    print('First element not greater');
}

case-when子句計算任何一個boolean類型的值,值為true代表可以執行本Case可選項邏輯,為false繼續執行下一個Case可選項,並不會退出整個Switch語句。


我的本博客原地址:https://ntopic.cn/p/2023101301


Add a new 评论

Some HTML is okay.