Dart之流程控制

一、前言
什么是流程控制呢?
你可以先把它理解成生活里的“选择”和“重复”。
比如今天要不要出门,要看天气;如果晴天就去爬山,如果下雨就待在家。再比如学一个知识点,不是看一遍就结束,而是反复练习,直到学会为止。
Dart 里的流程控制也是这个意思:让代码根据条件选择不同分支,或者让某段代码重复执行多次。
这一篇我们系统讲清楚 Dart 中的条件语句、循环语句和跳转语句。
二、一句话理解
流程控制就是控制代码执行路线:条件语句负责“选择走哪条路”,循环语句负责“重复做一件事”,跳转语句负责“提前停止或跳过”。
简单说:
- 条件语句:做选择。
- 循环语句:做重复。
- 跳转语句:控制循环中的中断和跳过。
三、流程控制总览
Dart 中常见流程控制可以分成三类:
| 分类 | 常见语法 | 作用 |
|---|---|---|
| 条件语句 | if、if-else、switch、条件表达式 |
根据条件选择执行路径 |
| 循环语句 | for、for-in、while、do-while |
重复执行代码 |
| 跳转语句 | break、continue、标签 |
控制循环提前结束或跳过 |
这三类组合起来,就能表达大部分程序执行逻辑。
四、条件语句
条件语句用于根据不同条件执行不同代码。
生活中我们会说:“如果天气晴朗,就去爬山。”代码里也是一样。
4.1 if 语句
if 用于最简单的条件判断。
void main() {
String weather = '晴朗';
if (weather == '晴朗') {
print('我们就去爬山');
}
}
只有当条件表达式为 true 时,代码块才会执行。
语法结构:
if (条件表达式) {
// 条件成立时执行
}
if 适合只有一个条件需要判断的场景。
4.2 if-else 语句
if-else 用于二选一。
void main() {
String weather = '小雨';
if (weather == '晴朗') {
print('我们就去爬山');
} else {
print('待在家里面');
}
}
如果 if 条件成立,执行 if 代码块;否则执行 else 代码块。
语法结构:
if (条件表达式) {
// 条件为 true 时执行
} else {
// 条件为 false 时执行
}
4.3 if-else if-else 多分支语句
当有多个条件需要依次判断时,可以使用多分支。
void main() {
String weather = '小雨';
if (weather == '晴朗') {
print('去爬山');
} else if (weather == '多云') {
print('去打球');
} else {
print('待在家里面');
}
}
多分支会从上往下依次判断,哪个条件先满足,就执行哪个分支。
要注意:如果前面的条件已经成立,后面的条件不会再判断。
4.4 守卫语句
守卫语句是一种提前返回的写法。
它通常用于:如果条件不满足,就直接结束当前函数,不再继续往下执行。
void hello(String name) {
if (name != 'Dart') return;
print('hello, $name!');
}
void main() {
hello('Dart'); // hello, Dart!
hello('Java'); // 没有输出
}
守卫语句的价值是减少嵌套。
不使用守卫语句时,可能会写成这样:
void hello(String name) {
if (name == 'Dart') {
print('hello, $name!');
}
}
逻辑简单时两种都可以;当条件越来越多时,守卫语句可以让主流程更清楚。
4.5 switch 语句
switch 适合处理有限数量的离散值。
比如天气只能是晴朗、多云、小雨等固定值,就可以用 switch。
void main() {
String weather = '晴朗';
switch (weather) {
case '晴朗':
print('去爬山');
break;
case '多云':
print('去打球');
break;
default:
print('待在家');
}
}
switch 的结构:
switch (表达式) {
case 值1:
// 匹配值1时执行
break;
case 值2:
// 匹配值2时执行
break;
default:
// 都不匹配时执行
}
适合 switch 的场景:
- 状态值判断。
- 枚举值判断。
- 固定字符串或整数匹配。
- 分支较多但每个分支比较清晰。
4.6 条件表达式
条件表达式也叫三目运算符,是简洁版的 if-else。
void main() {
String weather = '小雨';
String result = weather == '晴朗' ? '去爬山' : '待在家';
print(result);
}
语法结构:
条件 ? 条件成立时的结果 : 条件不成立时的结果
它适合简单的二选一赋值。
如果逻辑很长,不建议强行写三目运算符,使用 if-else 更清楚。
五、循环语句
循环语句用于重复执行代码。
生活里反复练习,直到掌握;代码里反复执行,直到条件不再满足。
5.1 for 循环
for 循环适合明确知道循环次数的场景。
void main() {
for (int i = 0; i < 5; i++) {
print('hello, Dart!');
}
}
for 循环由三部分组成:
for (初始化表达式; 条件表达式; 更新表达式) {
// 循环体
}
执行流程:
- 先执行初始化表达式。
- 判断条件表达式。
- 条件为
true,执行循环体。 - 执行更新表达式。
- 回到第 2 步继续判断。
- 条件为
false,退出循环。
用计数器重复执行固定次数时,for 很合适。
5.2 增强 for 循环
增强 for 循环也常叫 for-in,适合遍历集合。
void main() {
List<int> numbers = [1, 2, 2, 5];
for (int value in numbers) {
print(value);
}
}
相比普通 for,for-in 更关注“逐个拿出集合里的元素”,不需要自己管理下标。
适合:
- 遍历
List。 - 遍历
Set。 - 不关心元素下标,只关心元素本身。
如果需要下标,普通 for 更合适。
void main() {
List<String> names = ['Tom', 'Jerry'];
for (int i = 0; i < names.length; i++) {
print('$i: ${names[i]}');
}
}
5.3 while 循环
while 循环适合不知道具体循环次数,但知道继续条件的场景。
void main() {
int i = 0;
while (i < 5) {
print('hello, Dart!');
i++;
}
}
语法结构:
while (条件表达式) {
// 循环体
// 更新条件
}
while 会先判断条件,再决定是否执行循环体。
如果一开始条件就是 false,循环体一次都不会执行。
5.4 do-while 循环
do-while 至少会执行一次。
void main() {
int i = 0;
do {
print('hello, Dart!');
i++;
} while (i < 5);
}
它和 while 的区别是:
while:先判断,再执行。do-while:先执行一次,再判断。
适合“至少要执行一次”的场景,比如先让用户输入一次,再判断是否继续。
5.5 四种循环怎么选
| 循环 | 适合场景 |
|---|---|
for |
明确知道循环次数 |
for-in |
遍历集合元素 |
while |
不确定次数,但有继续条件 |
do-while |
至少执行一次,再判断是否继续 |
六、跳转语句
跳转语句用于改变循环的正常执行节奏。
6.1 break 语句
break 用于立即退出当前循环。
void main() {
for (int i = 0; i < 5; i++) {
if (i == 3) {
break;
}
print('hello$i');
}
}
输出:
hello0
hello1
hello2
当 i == 3 时,循环直接结束,所以不会打印 hello3 和 hello4。
6.2 continue 语句
continue 用于跳过本次循环,直接进入下一次循环。
void main() {
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue;
}
print('hello$i');
}
}
输出:
hello0
hello1
hello2
hello4
当 i == 3 时,只跳过本次打印,循环本身不会结束。
一句话区分:
break:整个循环结束。continue:本次循环结束,下一次继续。
6.3 标签
标签用于跳出指定层级的循环。
在多层嵌套循环中,普通 break 只能跳出当前这一层。如果想跳出外层循环,可以使用标签。
void main() {
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break outer;
}
print('i:$i, j:$j');
}
}
}
输出:
i:0, j:0
i:0, j:1
i:0, j:2
i:1, j:0
标签能解决多层跳出问题,但不要滥用。嵌套太深时,通常也意味着代码可以考虑拆成函数。
七、常见注意点
7.1 if 可以嵌套,但不建议过深
嵌套太深会让代码越来越难读。
if (isLogin) {
if (hasPermission) {
if (isActive) {
print('允许访问');
}
}
}
可以用守卫语句优化:
void checkAccess(bool isLogin, bool hasPermission, bool isActive) {
if (!isLogin) return;
if (!hasPermission) return;
if (!isActive) return;
print('允许访问');
}
主流程会清楚很多。
7.2 防止死循环
死循环就是循环条件一直为 true,程序无法正常退出。
void main() {
int i = 0;
while (i < 5) {
print(i);
// 忘记 i++,会一直循环
}
}
写循环时一定要检查:
- 初始值是否正确。
- 条件是否会变成
false。 - 更新表达式是否执行。
7.3 switch 适合离散值,不适合复杂条件
如果判断的是固定状态,switch 很清楚。
switch (status) {
case 'paid':
print('已支付');
break;
case 'cancelled':
print('已取消');
break;
}
如果条件是范围判断,比如分数区间,用 if-else 更自然。
if (score >= 90) {
print('优秀');
} else if (score >= 60) {
print('及格');
} else {
print('不及格');
}
7.4 条件表达式不要写太复杂
三目运算符适合简单二选一。
String result = score >= 60 ? '及格' : '不及格';
如果嵌套三目,读起来会很费劲。可读性比少写几行更重要。
八、总结
这一篇我们系统梳理了 Dart 中的流程控制。
流程控制本质上解决两类问题:
- 选择:根据条件决定执行哪段代码。
- 重复:让代码执行多次,直到满足终止条件。
条件语句包括:
ifif-elseif-else if-else- 守卫语句
switch- 条件表达式
循环语句包括:
forfor-inwhiledo-while
跳转语句包括:
break:结束循环。continue:跳过本次循环。- 标签:跳出指定层级循环。
最后记住一条原则:流程控制不是为了把逻辑写得复杂,而是为了让代码执行路线更清楚。条件少时用简单判断,分支固定时用 switch,重复次数明确时用 for,遍历集合时用 for-in,循环条件不确定时用 while。
浙公网安备 33010602011771号