Dart2基礎--流程控制語句,異常

if and else

Dart支持 if 語句,else 語句是可選的,例如:

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

不同於JavaScript,這裏的條件必須是boolean值,不能是其他的任何值。

for循環

你可以使用標準的 for 循環來做遍歷:

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

Dart2中 for 循環裏面的閉包可以捕獲索引的值。例如:

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

此段代碼先輸出 0 ,再輸出 1 ,正是我們期望的結果。然而,這個例子在JavaScript中的輸出爲:先輸出 2 ,再輸出 2.
如果循環的對象是一個可迭代的對象,你可以使用 forEach() 方法。如果你不需要知道當前迭代的計數器,使用 forEach() 是一個很好的選擇。

candidates.forEach((candidate) => candidate.interview());

想List和Set這樣的可迭代類也支持 for-in 這種形式的迭代方式:

var collection = [0, 1, 2];
for (var x in collection) {
  print(x); // 0 1 2
}

While 和 do-while循環

一個 while 循環在循環之前計算表達式的值:

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

一個 do-while 再循環開始之後計算表達式的值:

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

break 和 continue

使用 break 來停止循環:

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

使用 continue 來跳到下一個循環:

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

如果你使用Iterable(如列表List和集合Set),則可以使用如下方式實現上面的例子:

candidates
    .where((c) => c.yearsExperience >= 5)
    .forEach((c) => c.interview());

Switch 和 case

Dart中的Switch 語句使用 == 來比較 整型、字符串或者編譯時常量。參與比較的對象必須全部是同一種類的實例(不能是該類的任意子類型的實例),並且該類不能覆寫 == .在switch 語句中可以使用枚舉類型。

每一個不爲空的 case 語句都以一個 break 語句結尾,也可以以 continue ,rethrow,throw,或者return 作爲結尾。
一下示例省略了case子句中的break語句,從而產生錯誤:

var command = 'OPEN';
switch (command) {
  case 'OPEN':
    executeOpen();
    // ERROR: Missing break

  case 'CLOSED':
    executeClosed();
    break;
}

然而,Dart支持空的 case 子句,例如:

var command = 'CLOSED';
switch (command) {
  case 'CLOSED': // Empty case falls through.
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

也可以使用一個 continue 語句和一個標籤實現如下功能:

var command = 'CLOSED';
switch (command) {
  case 'CLOSED':
    executeClosed();
    continue nowClosed;
  // Continues executing at the nowClosed label.

  nowClosed:
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

一個 case 子句可以有本地變量,這些變量的可見性僅僅在該子句的範圍內。

Assert

如果一個 boolean 條件爲 false 則使用一個 assert 語句來中斷正常執行:

// Make sure the variable has a non-null value.
assert(text != null);

// Make sure the value is less than 100.
assert(number < 100);

// Make sure this is an https URL.
assert(urlString.startsWith('https'));

注意Assert語句對生產環境的代碼沒有影響,它們僅僅作用在開發環境中。Flutter在調試模式(debug mode)纔會啓用 assert。僅限開發時使用的工具如 dartdevc 通常默認支持 assert。一些工具,例如 dartdart2js,通過命令行標誌 –enable-asserts 來支持 assert 。

要關聯一個消息給 assert,添加一個字符串作爲第二個參數即可:

assert(urlString.startsWith('https'),
    'URL ($urlString) should start with "https".');

當沒有 case 子句匹配時,使用 default 子句來執行代碼。

var command = 'OPEN';
switch (command) {
  case 'CLOSED':
    executeClosed();
    break;
  case 'PENDING':
    executePending();
    break;
  case 'APPROVED':
    executeApproved();
    break;
  case 'DENIED':
    executeDenied();
    break;
  case 'OPEN':
    executeOpen();
    break;
  default:
    executeUnknown();
}

異常

你的Dart代碼可以拋出或者捕獲異常。異常是一種錯誤,用來指示發生了一些意外事件。如果一個異常沒有被捕獲,通常程序將會被終止。
與Java不同,所有的Dart異常都是未檢查異常(unchecked exception)。方法不會聲明它們可能拋出哪些異常,所以你也不需要捕獲任何異常。

Dart提供異常(Exception)和錯誤(Error)類型,以及許多預定義的子類型。當然你也可以定義你自己的異常。然而,Dart程序可以拋出任意非null對象,不僅是異常和錯誤。

拋出異常

下面的例子就是拋出一個異常:

throw FormatException('Expected at least 1 section');

你也可以拋出任意對象:

throw 'Out of llamas!';

注意生產質量的代碼通常會拋出實現 Exception 或者 Error 的類型。

捕獲異常

捕獲異常可以停止異常的傳播(除非你重新拋出異常),捕獲異常給了你一個處理它的機會:

  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}

處理可能拋出多種異常的代碼,你可以指定多個 catch 子句。第一個與拋出異常的類型相匹配的catch子句會處理該異常。如果catch子句沒有指定類型,那麼該catch可以處理任意類型的異常:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}

如前面的例子所示,你可以使用 on 或者 catch 也可以二者都用。當你需要指定異常的類型時使用 on 。當你的異常處理需要使用到異常對象時使用 catch
你可以給 catch() 指定一個或者兩個參數。第一個參數代表拋出的異常,第二個參數是執行的堆棧路徑(一個 StackTrace 對象)。

try {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
}

要部分處理異常,使異常繼續傳播,使用 rethrow 關鍵字。

void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // Runtime error
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // Allow callers to see the exception.
  }
}

void main() {
  try {
    misbehave();
  } catch (e) {
    print('main() finished handling ${e.runtimeType}.');
  }
}

Finally

爲了保證一些代碼不管異常是否拋出都要執行,使用一個 finally 子句。如果沒有 catch 子句與異常相匹配,那麼這個異常會在 finally 子句執行完成之後繼續傳播。

try {
  breedMoreLlamas();
} finally {
  // Always clean up, even if an exception is thrown.
  cleanLlamaStalls();
}

finally 子句在任意匹配的 catch 子句之後執行。

try {
breedMoreLlamas();
} catch (e) {
print('Error: $e'); // Handle the exception first.
} finally {
cleanLlamaStalls(); // Then clean up.
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章