本系列教程大多翻译自 Dart 官网,因本人英语水平有限,可能有些地方翻译不准确,还请各位大佬斧正。如需转载请标明出处,谢绝 CSDN 爬虫党。
流程控制语句(Control flow statements)
你可以在 Dart 中使用下列代码去控制流程:
if
和else
for
循环while
和do-while
循环break
和continue
switch
和case
assert
你也可以使用 try-catch
和 throw
来处理异常。
if & else
Dart 支持 if 语句和可选的 else 语句:
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
和 JavaScript 不同的是,判断条件必须是布尔值。
For 循环
你可以对 iterate 化的变量进行循环遍历:
var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
message.write('!');
}
在 Dart 的 for
循环中,闭包体内会捕获索引的值,这样可以避免 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());
可 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());
区别:do-while
无论如何都会先执行一次遍历。
终止&跳过(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();
}
当使用 list
或 set
这样可 Iterable 化的变量时,你可能会这样写代码:
candidates
.where((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
分支(switch & case)
Dart 中的 switch 语句会用 ==
去比较数字、字符串或编译常量。比较的对象必须是同一类型的对象实例(不能像 JavaScript 那样模糊比较,即使其中一个操作数属于另一个对象的子类的实例也不行),并且类也不能重写 ==
运算符。
Note: 在 Dart 中,switch 语句会预先判断边界异常情况,比如在编译或代码扫描时。
按照规则,每一个非空的 case 分支要通过 break
语句进行结尾,使用 continue
, throw
,return
语句进行结尾也是可以的。
如果都没有分支匹配上,使用 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();
}
下面的例子忘记写 break
语句了,所以会报错:
var command = 'OPEN';
switch (command) {
case 'OPEN':
executeOpen();
// ERROR: Missing break
case 'CLOSED':
executeClosed();
break;
}
当然,Dart 支持空分支,允许下沉到下一个分支去统一处理:
var command = 'CLOSED';
switch (command) {
case 'CLOSED': // Empty case falls through.
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
如果你很希望分支下沉,使用 continue
语句并且指定 label,可以实现类似 goto 语句的功能:
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
语句 - assert(condition, optionalMessage)
- 如果条件为假,则会中断正常的执行流程。
// 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
里当做第二参数传入一段字符串:
assert(urlString.startsWith('https'), 'URL ($urlString) should start with "https".');
assert
的第一个参数是可以接受任何可以被转换为 Boolean 类型的对象(如果是函数,则判断函数返回值),如果参数为 true,断言就会成功,并且继续执行后面的代码。如果为 false , 断言就会终止程序并抛出一个 AssertionError 异常。
什么时候可以使用断言?,取决于你使用的库和框架:
- Flutter 允许在调试模式(debug mode)中使用;
- 只能在开发环境使用的库,比如dartdevc 默认支持断言;
- 有些苦,比如 dart 和 dart.dev/tools/dart2…,支持输入命令行:
--enable-asserts
来开启断言
在生产环境中,断言会自动被忽略,传入断言的参数也不会被执行。
系列文章:
Dart 简明教程 - 01 - Concepts & Variables
Dart 简明教程 - 02 - Functions
Dart 简明教程 - 03 - Operators
Dart 简明教程 - 04 - Control flow statements
Dart 简明教程 - 05 - Exceptions
Dart 简明教程 - 06 - Classes
Dart 简明教程 - 07 - Generics
Dart 简明教程 - 08 - Libraries and visibility
Dart 简明教程 - 09 - Asynchrony support
Dart 简明教程 - 10 - Generators & Isolates & Typedefs & Metadata...