流程控制与错误处理
Dart 的控制流语法与大多数 C 系语言类似,但引入了可选的集合内控制语句、模式匹配等现代特性。
相关关键字
if
/else
for
、for-in
、集合for
while
/do-while
break
/continue
switch
/case
(含when
模式)assert
try
/catch
/finally
/throw
- 标签语句(
label:
)
条件判断 if
/ else
条件必须是 bool
表达式:
if (isRaining()) {
bringRainCoat();
} else if (isSnowing()) {
wearJacket();
} else {
enjoySunshine();
}
dart
集合字面量、参数列表等上下文支持 if
:
final menu = [
'Home',
if (isLoggedIn) 'Profile' else 'Sign in',
];
dart
循环结构
for
for (var i = 0; i < 5; i++) {
print('index: $i');
}
dart
集合字面量支持循环(collection for
):
final squares = [for (var i = 0; i < 5; i++) i * i];
dart
for ... in
针对实现了 Iterable
的对象:
for (final user in users) {
user.notify();
}
dart
while
与 do ... while
while (!taskQueue.isEmpty) {
process(taskQueue.removeFirst());
}
do {
retryCount++;
} while (!taskCompleted && retryCount < 3);
dart
break
/ continue
for (final candidate in candidates) {
if (!candidate.isQualified) continue;
if (candidate.hasSignedOffer) break;
candidate.interview();
}
dart
switch
与模式匹配
Dart 3 起支持模式匹配(Pattern Matching),不仅能比较字面量,还能解构记录、列表等:
switch (event) {
case LogoutEvent():
handleLogout();
case LoginEvent(user: final user) when user.isAdmin:
handleAdminLogin(user);
case LoginEvent(user: final user):
handleUserLogin(user);
default:
logUnknown(event);
}
dart
注意:
switch
默认“穷举检查”,若覆盖了所有情况可省略default
。- 模式中可使用
when
关键字添加额外条件。 - 旧语法
case 'value': ... break;
仍然有效。
assert
assert(condition, message)
仅在调试模式生效,常用于验证前置条件:
void updateUser(User user) {
assert(user.id != null, 'User must be persisted before update');
// ...
}
dart
异常处理
Dart 使用 try
/ catch
/ finally
结构,可以捕获具体类型或处理栈追踪:
try {
await api.fetch();
} on TimeoutException catch (e) {
showToast('请求超时: ${e.message}');
} catch (e, stackTrace) {
reportError(e, stackTrace);
} finally {
hideSpinner();
}
dart
抛出异常使用 throw
:
void validateAge(int age) {
if (age < 0) throw ArgumentError.value(age, 'age', '不能为负数');
}
dart
使用标签控制嵌套循环
outerLoop:
for (final row in matrix) {
for (final value in row) {
if (value == target) break outerLoop;
}
}
dart
通过掌握以上控制结构,可以在 Dart 中实现清晰可靠的流程控制逻辑;模式匹配和集合内控制表达式让声明式风格更加简洁。
示例扩展(保留旧版代码体验)
forEach
与命令式/函数式对比
void main() {
final candidates = <Candidate>[
Candidate('Alice', 6),
Candidate('Bob', 3),
];
// 命令式
for (var i = 0; i < candidates.length; i++) {
final candidate = candidates[i];
if (candidate.yearsExperience < 5) {
continue;
}
candidate.interview();
}
// 函数式
candidates
.where((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
}
class Candidate {
final String name;
final int yearsExperience;
Candidate(this.name, this.yearsExperience);
void interview() => print('Interview $name');
}
dart
传统 switch
示例(使用 break
)
void main() {
final 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();
}
}
void executeClosed() {}
void executePending() {}
void executeApproved() {}
void executeDenied() {}
void executeOpen() {}
void executeUnknown() {}
dart
assert
与标签循环
void processMatrix(List<List<int>> matrix, int target) {
assert(matrix.isNotEmpty, 'matrix must not be empty');
outer:
for (final row in matrix) {
for (final value in row) {
if (value == target) {
print('found $value');
break outer;
}
}
}
}
dart
↑