if-else 语句
基本的条件控制:
int age = 20;
if (age >= 18) {
print("成年人");
} else if (age >= 12) {
print("青少年");
} else {
print("儿童");
}
switch-case 语句
多分支条件控制:
String grade = 'A';
switch (grade) {
case 'A':
print("优秀");
break;
case 'B':
print("良好");
break;
case 'C':
print("及格");
break;
default:
print("不及格");
}
for 循环
标准 for 循环
for (int i = 0; i < 5; i++) {
print(i); // 输出 0 到 4
}
for-in 循环
var numbers = [1, 2, 3, 4, 5];
for (var number in numbers) {
print(number);
}
forEach 循环
var fruits = ['苹果', '香蕉', '橙子'];
fruits.forEach((fruit) => print(fruit));
while 循环
while 循环
int count = 0;
while (count < 5) {
print(count);
count++;
}
do-while 循环
int num = 1;
do {
print(num);
num *= 2;
} while (num <= 16);
break 和 continue
break 语句
for (int i = 0; i < 10; i++) {
if (i == 5) {
break; // 跳出循环
}
print(i);
}
continue 语句
for (int i = 0; i < 5; i++) {
if (i == 2) {
continue; // 跳过当前迭代
}
print(i);
}
标签语句
outerLoop: for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break outerLoop; // 跳出外层循环
}
print("$i, $j");
}
}
异常处理流程
try {
int result = 12 ~/ 0; // 除以零异常
print(result);
} on IntegerDivisionByZeroException {
print("不能除以零");
} catch (e) {
print("捕获到异常:$e");
} finally {
print("总是执行");
}
assert 语句
在开发模式下进行断言:
int age = -5;
assert(age >= 0, "年龄不能为负数");
条件表达式
三元运算符
int number = 15;
String result = number % 2 == 0 ? "偶数" : "奇数";
?? 运算符
String? name;
String displayName = name ?? "匿名用户";
最佳实践
- 合理使用控制流语句,避免过度嵌套
- 优先使用 for-in 和 forEach 进行集合遍历
- 适当使用 break 和 continue 控制循环流程
- 注意异常处理的完整性
- 合理使用断言进行开发时的调试
实战案例:一个方法里的类型分发
ygking_json_to_dart_model 的 convertJsonToDart 入口,核心就是一段类型分发:
String convertJsonToDart(String jsonStr, String className) {
try {
final dynamic jsonData = json.decode(jsonStr);
if (jsonData is Map<String, dynamic>) {
_generateClass(jsonData, className, buffer, className);
} else if (jsonData is List &&
jsonData.isNotEmpty &&
jsonData[0] is Map<String, dynamic>) {
// 数组:取第一个元素当模板
_generateClass(jsonData[0], className, buffer, className);
} else {
return '// 错误: JSON格式无效\n// 输入必须是对象或对象数组';
}
return buffer.toString();
} catch (e) {
return '// 错误: JSON格式无效\n// $e';
}
}
这段 if-else if-else 有三个值得说的地方:
-
用
is做类型分发,而不是runtimeType ==。is还顺带做了类型提升——进到第一个分支里,jsonData就已经被编译器当成Map<String, dynamic>,直接传给_generateClass不用强转。这是 Dart 控制流里最实用的特性之一。 -
条件里塞了业务规则:
jsonData is List && jsonData.isNotEmpty && jsonData[0] is Map。空数组直接判无效——因为空数组没有结构信息,生成不出来类。控制流的条件应该表达业务语义,而不是单纯的类型检查。“是 List”不够,“是能生成类的 List”才够。 -
else 分支返回错误注释,而不是抛异常。前面错误处理那篇讲过,这是工具场景的刻意选择。控制流和错误处理是一体的:
else在这里承担了”兜底”职责,保证方法所有路径都有返回值,调用方永远拿到一个 String。
总结
控制流语句本身都很简单,难的是条件里写什么:把业务语义塞进条件(“是能生成类的 List”而不是”是 List”),保证每个分支都有明确归宿,代码读起来就顺。配合 is 的类型提升,Dart 的类型分发写起来比多数语言都省事。
