一、Control flow statements(流程控制语句)
-
if
andelse
for
-
while
anddo-while
loops -
break
andcontinue
-
switch
andcase
-
assert
(仅在checked模式有效)
Dart中的流程控制语句总体来说和大多数语言的流程控制语句相似,除了以下特别要注意的,其他的就不再多介绍。
1.Dart for
循环中的闭包会捕获循环的 index 索引值, 来避免 JavaScript 中常见的问题。
var callbacks = [];
for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());
输出的结果为所期望的 0
和 1
。但是 上面同样的代码在 JavaScript 中会打印两个 2
。
2.如果要遍历的对象实现了 Iterable 接口,则可以使用 forEach()
方法。如果没必要当前遍历的索引,则使用 forEach()
方法 是个非常好的选择:
candidates.forEach((candidate) => candidate.interview());
List 和 Set 等实现了 Iterable
接口的类还支持 for-in
形式的 遍历:
var collection = [0, 1, 2];
for (var x in collection) {
print(x);
}
3.Switch and case
Dart 中的 Switch 语句使用 ==
比较 integer、string、或者编译时常量。 比较的对象必须都是同一个类的实例(并且不是 其之类),class 必须没有覆写 ==
操作符。 Enumerated types 非常适合 在 switch
语句中使用。
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 中的空 case
语句中可以不要 break
语句:
var command = 'CLOSED';
switch (command) {
case 'CLOSED': // Empty case falls through.
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
如果你需要实现这种继续到下一个 case 语句中继续执行,则可以 使用 continue 语句跳转到对应的标签(label)处继续执行:
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(断言)
如果条件表达式结果不满足需要,则可以使用 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
方法的参数可以为任何返回布尔值的表达式或者方法。 如果返回的值为 true, 断言执行通过,执行结束。 如果返回值为 false, 断言执行失败,会抛出一个异常 AssertionError)。
三、Exceptions(异常)
Dart 提供了 Exception 和 Error 类型, 以及一些子类型。你还可以定义自己的异常类型。但是, Dart 代码可以 抛出任何非 null
对象为异常,不仅仅是实现了 Exception
或者 Error
的对象。
和 Java 不同的是,所有的 Dart 异常是非检查异常。 方法不一定声明了他们所抛出的异常, 并且不要求捕获任何异常。
3.1. Throw
- 抛出固定类型的异常
throw new FormatException('Expected at least 1 section');
- 抛出任意类型的异常
throw 'Out of llamas!';
- 若抛出异常是一个表达式,所以可以在
=>
语句中使用,也可以在其他能使用表达式的地方抛出异常。
distanceTo(Point other) =>
throw new UnimplementedError();
3.2. Catch
- 捕获异常可以避免异常继续传递(你重新抛出rethrow异常除外)。 捕获异常给你一个处理 该异常的机会:
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
- 将可能出现异常的代码放置到
try
语句中,可以通过on
语句来指定需要捕获的异常类型,使用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 对象)。
...
} on Exception catch (e) {
print('Exception details:\n $e');
} catch (e, s) {
print('Exception details:\n $e');
print('Stack trace:\n $s');
}
3.3. rethrow
- rethrow语句用来处理一个异常,同时希望这个异常能够被其它调用的部分使用。
final foo = '';
void misbehave() {
try {
foo = "1";
} catch (e) {
print('2');
rethrow;// 如果不重新抛出异常,main函数中的catch语句执行不到
}
}
void main() {
try {
misbehave();
} catch (e) {
print('3');
}
}
3.4. Finally
- 要确保某些代码执行,不管有没有出现异常都需要执行,可以使用 一个 finally 语句来实现。如果没有 catch 语句来捕获异常, 则在执行完 finally 语句后, 异常被抛出了:
try {
breedMoreLlamas();
} catch(e) {
print('Error: $e'); // Handle the exception first.
} finally {
// 没有捕捉到的异常,即使没有rethrow最终都会执行到这里
cleanLlamaStalls();
}
网友评论