Dart代码可以使用下面的控制流语句:
if
和else
for
循环while
和do-while
循环break
和continue
switch
和case
assert
如Exceptions所描述的,可用trt-catch
和throw
来影响控制流语句。
if和else
Dart支持if
语句与可选的else
语句,如下面例子显示。还请查阅conditional expressions。
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
与JavaScript不同,条件必须是布尔值。查阅更多Booleans信息。
For循环
遍历使用标准的for
循环。例如:
var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
message.write('!');
}
Dart的闭包捕获for
循环索引值。避免JavaScrip常见的陷阱。例如,考虑下:
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());
Iterable类如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
语句中正常工作。
注意:在Dart中switch语句有限的情况下适用于,诸如interpreter和scanners。
规则,每个非空的case
子句于break
语句结尾。其他可行的方式是,非空case
子句用continue
、throw
或return
语句结束。 当没匹配到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();
}
下面的示例在case
子句中省略break
语句,导致错误:
var command = 'OPEN';
switch (command) {
case 'OPEN':
executeOpen();
// ERROR: Missing break
case 'CLOSED':
executeClosed();
break;
}
但是, Dart允许下降(fall-through)的方式支持空case
子句:
var command = 'CLOSED';
switch (command) {
case 'CLOSED': // 空case下降.
case 'NOW_CLOSED':
//CLOSED和NOW_CLOSED都运行.
executeNowClosed();
break;
}
可以使用continue
语句和标签在下降(fall-through)中:
var command = 'CLOSED';
switch (command) {
case 'CLOSED':
executeClosed();
continue nowClosed;
// 继续执行nowClosed标签.
nowClosed:
case 'NOW_CLOSED':
//CLOSED和NOW_CLOSED都运行.
executeNowClosed();
break;
}
case
子句里定义的变量,可见性仅在于子句作用域内。
断言
使用assert
语句中断条件为false的正常执行。您可以在整个教程中找到断言语句的示例。这里有更多的:
// 确保变量为非空值
assert(text != null);
//确保值小于100
assert(number < 100);
// 确保是一个https链接
assert(urlString.startsWith('https'));
注意:assert语句在生产代码不起作用,它们只用于开发。Flutter在debug模式开启assert。开发工具如dartdevc一般默认支持断言。一些工具如dart和dart2js通过命令行参数
--enable-asserts
支持。
若要将消息附加到断言, 将字符串添加到第二个参数。
assert(urlString.startsWith('https'),
'URL ($urlString) should start with "https".');
assert
的第一个参数可以是任何解析为boolean值得表达式。如果表达式的值为true,断言成功并继续执行。如果为false,断言失败抛出一个异常(AssertionError)。
异常
Dart代码可以抛出和捕获异常。异常指示发生意外事件的错误。如果异常没有捕获,引发异常的isolate将被挂起,通常isolate和程序被终止。 对比Java,所有的dart异常都是未检异常。方法不用声明它要抛出的异常,且不强制捕获任何异常。 Dart提供Exception和Error类型,以及许多预定义的子类。当然您也可以定义自己的一场。但是, Dart 程序可以抛出任何非nul对象, 而不只是Exception和Error对象。
Throw
下面是抛出或引发异常的示例:
throw FormatException('Expected at least 1 section');
也可以抛出任意对象:
throw 'Out of llamas!';
注意:生成的代码抛出类型一般会实现Error或Exception。 由于抛出异常是一个表达式,可以把抛出异常用在=>语句中,以及其他任何允许表达式的地方。
void distanceTo(Point other) => throw UnimplementedError();
Catch
捕捉或捕获,阻止异常传播 (除非rethrow 异常)。catch一个异常给你一个处理它的机会。
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
捕获代码可以处理不止一个异常类型,可指定多个catch子句。第一个匹配抛出类型对象catch子句处理异常。如果 catch 子句未指定类型, 则该子句可处理任何抛出对象类型(无catch子句匹配情况):
try {
breedMoreLlamas();
} on OutOfLlamasException {
//指定一个异常
buyMoreLlamas();
} on Exception catch (e) {
// 任何其他这是一个异常
print('Unknown exception: $e');
} catch (e) {
// 无指定类型,处理所有
print('Something really unknown: $e');
}
on type catch(e)的语法实在别扭!
如果只要部分处理异常, 允许它继续传播, 请使用 rethrow 关键字。
void misbehave() {
try {
dynamic foo = true;
print(foo++); // 运行时 error
} catch (e) {
print('misbehave() partially handled ${e.runtimeType}.');
rethrow; // 运行调用者见到异常
}
}
void main() {
try {
misbehave();
} catch (e) {
print('main() finished handling ${e.runtimeType}.');
}
}
Finally
使用finally
子句确保某些代码无论是否引发异常都执行。如果没有匹配catch
子句异常, 则在最后一个子句运行后将传递异常:
try {
breedMoreLlamas();
} finally {
// 总是清理, 即使引发异常。
cleanLlamaStalls();
}
finally
子句在匹配任何catch
子句后执行:
try {
breedMoreLlamas();
} catch (e) {
print('Error: $e'); // 首先处理异常
} finally {
cleanLlamaStalls(); //然后清理.
}
阅读library速览的Exceptions部分了解更多内容。