Control flow statements
控制流程语句
流程控制相关的语句主要分为以下几类:
条件流程
- if...else
- switch...case
循环流程
- for循环
- while循环
- do...while循环
中断流程
- continue
- break
- return
异常流程(异常捕获/异常处理)
- try...catch
流程控制用于根据需要组合不同的语句、执行不同的处理,完成正确的流程逻辑。
条件流程
根据条件的满足情况,来执行不同的逻辑代码块。Dart支持if
、switch
条件语句。
if语句
if
用于当满足条件(结果为true
)执行对应的代码块;if...else
中当if
条件不满足时,执行else
的代码块。
bool condition = Random().nextBool();
// 单分支
if(condition){
// condition = true 时执行逻辑
}
// 二分支
if(condition){
// condition = true 时执行逻辑
}else{
// condition = false 时执行逻辑
}
如果需要多个分支,可以使用else if
继续添加条件。
如下所示,将 [0,100]
的分数通过if...else if...else
转化为 A~E
五个等级:
// E: [0,60)
// D: [60,70)
// C: [70,80)
// B: [80,90)
// A: [90,100]
String getLevel(double grade) {
String level = '';
if (grade >= 0 && grade < 60) {
level = 'E';
} else if (grade < 70) {
level = 'D';
} else if (grade < 80) {
level = 'C';
} else if (grade < 90) {
level = 'B';
} else {
level = 'A';
}
return level;
}
switch 语句
if条件判断的是真假(bool
),来执行对应的分支。switch
针对一般对象进行比较,相等时执行对应分支。通过对比switch(value)
条件中的值与case value_for_match:
的值,可以方便的实现多分支结构。
switch
语句的语法和条件说明:
switch (status){
case status_1:
// status == status_1 时执行逻辑
break;
case status_2:
// status == status_2 时执行逻辑
break;
default:
// 其余情况执行逻辑
}
switch
后面 ()
中的值
与case
对应的匹配值
进行比较,如果满足则执行case
对应的分支。
分支内使用break;
结束switch
的执行,否则将会继续匹配后面的case
条件;分支内也可以使用return
返回,不执行后续的操作(通常为函数返回)。
如下,通过信号灯的状态枚举TrafficLightStatus
,使用switch
判断枚举值,返回不同的状态描述:
import 'dart:math';
main(){
String status = getLightStatus(TrafficLightStatus.values[Random().nextInt(4)]);
print(status); // 输出随机的灯状态的描述
}
enum TrafficLightStatus{
red,
yellow,
blue,
none
}
String getLightStatus(TrafficLightStatus status){
String result = "";
switch (status){
case TrafficLightStatus.red:
result = "红灯,禁止通行";
break;
case TrafficLightStatus.yellow:
result = "黄灯,请您稍后";
break;
case TrafficLightStatus.blue:
result = "绿灯,应许通行";
break;
case TrafficLightStatus.none:
result = "信号灯故障,请联系维修人员";
break;
}
return result;
}
关于函数/方法的定义使用,可以后面再了解。此处主要了解,根据switch (status)
中status
的不同值,判断并执行不同的case
条件语句。
运行查看。
PS > dart run .\FlowControl.dart
信号灯故障,请联系维修人员
PS > dart run .\FlowControl.dart
绿灯,应许通行
PS > dart run .\FlowControl.dart
绿灯,应许通行
PS > dart run .\FlowControl.dart
黄灯,请您稍后
PS > dart run .\FlowControl.dart
红灯,禁止通行
case
分支结构的校验对象原则上可以是任何类型的对象,但 必须是常量
。比如一个自定义的class
,需要通过const
修饰符指定为常量,才能放在case
关键字后面。此外,自定义类型也不能重写
==
操作符。
循环流程
循环语句可以做到「能够根据条件不断执行循环体」,这是复杂的算法和数据结构得以实现的基础。Dart中主要提供了for
和while
循环。
从大的方面来说,由于程序执行完毕就会终止,所以无论任何软件,其在运行中必定有个循环来让应用不会关闭。而小的方面,一切的遍历操作都离不开循环流程。
循环最基础的作用就是,重复执行某个操作或某段代码;其次就是遍历数据内的所有元素,并进行相关处理。
标准for循环
for loop
标准for
循环的结构如下:
for ( startExp ; condition ; eachLoopExp ) {
loopBody
}
for
关键字后的括号中有三个部分,通过 ;
隔开。其中 startExp
是进入循环体前执行的表达式,只会执行一次; condition
是 bool
型的变量或结果,是循环的条件,只有为 true
时,才允许执行循环体;eachLoopExp
是在每次循环体结束之后触发的表达式,一般用于修改 condition
的条件。
如下,标准 for
循环在一个StringBuffer
的末尾重复写入5个!
:
var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
message.write('!');
}
print(message); // Dart is fun!!!!!
如下,标准 for
循环实现遍历并输出列表中的元素:
List<String> cnBigNumUnits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
for (int i = 0; i < cnBigNumUnits.length; i++) {
print(cnBigNumUnits[i]);
}
对于循环中的eachLoopExp
来说,主要用于在本次循环结束后修改循环的条件;真正决定是否继续执行循环体的判断是中间的condition
结果。
标准for
循环还可以修改为下面的形式:
List<String> cnBigNumUnits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
int i = 0;
bool condition = i < cnBigNumUnits.length;
for (; condition; ) {
print(cnBigNumUnits[i]);
i++;
condition = i < cnBigNumUnits.length;
}
// 或者
i = 0;
for (; i < cnBigNumUnits.length; ) {
print(cnBigNumUnits[i]);
i++;
}
for...in 循环
for...in
循环可以直接遍历访问列表的元素,直接获取元素,而不涉及索引。它是对列表遍历的一个语法糖。在无需索引,只是遍历元素时非常便捷。
List<String> cnBigNumUnits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
for (String element in cnBigNumUnits) {
print(element);
}
forEach遍历
forEach
遍历是一个类方法,与for...in
一样,直接访问元素。其本质也是使用for...in
处理的封装或语法糖。
void forEach(void action(E element)) {
for (E element in this) action(element);
}
比如forEach
遍历输出元素。
List<String> cnBigNumUnits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
cnBigNumUnits.forEach((e)=>print(e));
再感受一下forEach
的简洁
cnBigNumUnits.forEach(print);
while 循环
while
循环比较简单,只要满足条件就执行循环体,执行完后再次判断循环条件是否满足,满足则再次执行循环,不满足则退出循环。
while (condition) {
loopBody
}
while
相对容易产生死循环,如果condition
不变的情况下,就是永远循环下去(直到系统资源耗尽,或者永不结束)。
因此,必须在 condition
或 loopBody
中动态修改循环条件。
使用while
循环输出列表元素:
int i = 0;
while (i < cnBigNumUnits.length){
print(cnBigNumUnits[i]);
i++;
}
while 循环是 for 循环的一种简写
while
循环相比for
循环,并不涉及执行的次数(或者列表的索引)。它可以通过使用迭代器完成遍历:
Iterator<String> it = cnBigNumUnits.iterator;
while(it.moveNext()){
print(it.current);
}
同样的,转化为for
循环,也可以实现迭代器的遍历:
Iterator<String> it = cnBigNumUnits.iterator;
for(;it.moveNext();){
print(it.current);
}
do...while 循环
do...while
的循环结构如下:
do {
loopBody
} while(condition)
也就是先执行一次循环体,然后根据条件判断再循环执行。与 for
和 while
循环没有本质区别,了解下即可。