Dart流程控制语句
流程控制语句
你可以使用下面的语句来控制 Dart 代码的执行流程:
if
和else
for
循环while
和do
-while
循环break
和continue
switch
和case
assert
使用 try-catch
和 throw
也能影响控制流,详情参考异常部分。
If 和 Else
Dart 支持 if - else
语句,其中 else
是可选的,比如下面的例子。你也可以参考条件表达式。
1 | if (isRaining()) { |
Dart 的 if 语句中的条件必须是布尔值而不能为其它类型。详情请查阅 布尔值。
For 循环
你可以使用标准的 for
循环进行迭代。例如:
1 | var message = StringBuffer('Dart is fun'); |
在 Dart 语言中,for
循环中的闭包会自动捕获循环的 索引值 以避免 JavaScript 中一些常见的陷阱。假设有如下代码:
1 | var callbacks = []; |
上述代码执行后会输出 0
和 1
,但是如果在 JavaScript 中执行同样的代码则会输出两个 2
。
如果要遍历的对象是一个可迭代对象(例如 List 或 Set),并且你不需要知道当前的遍历索引,则可以使用 for-in
方法进行 遍历:
1 | for (final candidate in candidates) { |
可迭代对象同时可以使用 forEach() 方法作为另一种选择:
1 | var collection = [1, 2, 3]; |
While 和 Do-While
while
循环会在执行循环体前先判断条件:
1 | while (!isDone()) { |
do-while
循环则会 先执行一遍循环体 再判断条件:
1 | do { |
Break 和 Continue
使用 break
可以中断循环:
1 | while (true) { |
使用 continue
可以跳过本次循环直接进入下一次循环:
1 | for (int i = 0; i < candidates.length; i++) { |
Switch 和 Case
Switch 语句在 Dart 中使用 ==
来比较整数、字符串或编译时常量,比较的两个对象必须是同一个类型且不能是子类并且没有重写 ==
操作符。 枚举类型非常适合在 Switch
语句中使用。
Dart 中的 Switch 语句仅适用于有限的情况,比如使用解释器和扫描器的场景。
每一个非空的 case
子句都必须有一个 break
语句,也可以通过 continue
、throw
或者 return
来结束非空 case
语句。
不匹配任何 case
语句的情况下,会执行 default
子句中的代码:
1 | var command = 'OPEN'; |
下面的例子忽略了 case
子句的 break
语句,因此会产生错误:
1 | var command = 'OPEN'; |
但是,Dart 支持空的 case
语句,允许其以 fall-through 的形式执行。
1 | var command = 'CLOSED'; |
在非空 case
语句中想要实现 fall-through 的形式,可以使用 continue
语句配合 label 的方式实现:
1 | var command = 'CLOSED'; |
每个 case
子句都可以有局部变量且仅在该 case 语句内可见。
断言
在开发过程中,可以在条件表达式为 false 时使用 — assert(*条件*, *可选信息*)
; — 语句来打断代码的执行。你可以在本文中找到大量使用 assert 的例子。下面是相关示例:
1 | // Make sure the variable has a non-null value. |
assert
的第二个参数可以为其添加一个字符串消息。
1 | assert(urlString.startsWith('https'), |
assert
的第一个参数可以是值为布尔值的任何表达式。如果表达式的值为 true,则断言成功,继续执行。如果表达式的值为 false,则断言失败,抛出一个 AssertionError
异常。
如何判断断言是否生效?断言是否生效依赖开发工具和使用的框架:
- Flutter 在 调试模式 时生效。
- 一些开发工具比如 [
webdev serve
][] 通常情况下是默认生效的。 - 其他一些工具,比如
dart run
以及 [dart compile js
][] 通过在运行 Dart 程序时添加命令行参数--enable-asserts
使 assert 生效。
在生产环境代码中,断言会被忽略,与此同时传入 assert
的参数不被判断。