Dart2基础--流程控制语句,异常

Dart2中流程控制语句以及异常

    • if and else
    • for循环
    • While 和 do-while循环
    • break 和 continue
    • Switch 和 case
    • Assert
    • 异常
      • 抛出异常
      • 捕获异常
      • Finally

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。一些工具,例如 dart 和 dart2js,通过命令行标志 –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.
}

你可能感兴趣的:(Dart2,Flutter)