循环 Loops

一、标准 for 循环

语法:for(初始化; 条件; 迭代器) { 循环体 }

1:基础拼接字符串

void main() {
  var message = StringBuffer('wellcome to FoxDevelop.com');
  for (var i = 0; i < 5; i++) {
    message.write('!');
  }
  print(message); // wellcome to FoxDevelop.com!!!!!
}Code language: Dart (dart)

相当于,每次从0循环到5(不包括5)也就是i的值从0到4,一共五次,每次都在字符串wellcome to FoxDevelop.com的末尾拼接!

第一次 wellcome to FoxDevelop.com!

第二次 wellcome to FoxDevelop.com!!

第五次 wellcome to FoxDevelop.com!!!!!

特性:闭包捕获索引(和 JS 重要的一个区别)

Dart 每次循环都会绑定独立的 i,不会出现 JS 全部输出 2 的问题

void main() {
  var callbacks = [];
  for (var i = 0; i < 2; i++) {
    callbacks.add(() => print(i));
  }
  for (final c in callbacks) {
    c();
  }
}
// 输出
// 0
// 1
Code language: Dart (dart)

二、for-in 遍历可迭代对象 List/Set

适合不需要下标,只取值的时候

基础写法

class Candidate {
  void interview() => print("面试完成");
}

void main() {
  var candidates = [Candidate(), Candidate()];
  for (var candidate in candidates) {
    candidate.interview();
  }
}Code language: Dart (dart)

遍历candidates ,每次获取一个对象放到candidate ,然后调用它的interview函数。每读出下次就自动下一个。

进阶

for-in 搭配对象 Pattern 解构(Dart3+)

class Candidate {
  final String name;
  final int yearsExperience;
  Candidate({required this.name, required this.yearsExperience});
}

void main() {
  var candidates = [
    Candidate(name: "Lily", yearsExperience: 6),
    Candidate(name: "Tom", yearsExperience: 3),
  ];

  // 对象模式直接解构字段
  for (final Candidate(:name, :yearsExperience) in candidates) {
    print('$name 拥有 $yearsExperience 年工作经验');
  }
}
Code language: Dart (dart)

结合前面的解构,自动把对象里面的两个属性值赋值给:name, :yearsExperience 这两个变量,然后就可以通过这两个变量去进行后面的操作。

三、Iterable.forEach () 遍历方法

集合内置函数式遍历,传入回调处理每个元素

void main() {
  var collection = [1, 2, 3];
  collection.forEach(print);
  // 输出 1 2 3
}Code language: Dart (dart)

forEach是dart内置的函数,所有集合都可以通过.forEach调用。

四、while /do-while

1. while

先判断条件,再执行(可能一次都不运行),和其他语言基本一样,例如C C++ JAVA C#等等

bool isDone() => false;
void doSomething() => print("执行任务");

void main() {
  while (!isDone()) {
    doSomething();
    break;
  }
}Code language: Dart (dart)

先执行!isDone() 由于本来是false 取反后变成了true 添加符合 执行里面的

doSomething();
break;

遇到break,就终止循环,直接跳出while,如果bool isDone() => false; 改为true,则while里面的代码一次都不会执行,因为第一次判断就不符合。

2. do-while

先执行一次,再判断条件(至少运行 1 次)

bool atEndOfPage() => true;
void printLine() => print("打印一行");

void main() {
  do {
    printLine();
  } while (!atEndOfPage());
}
Code language: Dart (dart)

不管while后面的条件true或者false ,do {} 大括号中间的代码都会执行一次。

五、break /continue

break

直接终止整个循环,直接跳到循环的后面,如果break后面还有语句也不会执行。

bool shutDownRequested() => true;
void processIncomingRequests() => print("处理请求");

void main() {
  while (true) {
    if (shutDownRequested()) break;
    processIncomingRequests();
  }
  print("循环结束");
}
Code language: Dart (dart)

continue

跳过当前剩余代码,直接进入下一轮循环(直接到达循环体}的这个地方,然后进入到下一次)

传统 for 写法
class Candidate {
  final int yearsExperience;
  Candidate(this.yearsExperience);
  void interview() => print("面试");
}

void main() {
  var candidates = [Candidate(3), Candidate(6)];
  for (int i = 0; i < candidates.length; i++) {
    var candidate = candidates[i];
    if (candidate.yearsExperience < 5) {
      continue; // 经验不足5年,跳过面试
    }
    candidate.interview();
  }
}
Code language: Dart (dart)
函数式替代(不用 continue)
void main() {
  var candidates = [Candidate(3), Candidate(6)];
  candidates
      .where((c) => c.yearsExperience >= 5)
      .forEach((c) => c.interview());
}
Code language: Dart (dart)

六、标签 Label 嵌套循环控制

语法:标签名: 放在循环前,搭配 break 标签 / continue 标签

作用:多层嵌套时,直接跳出 / 跳过外层循环,而非仅内层

1. break + label

跳出双层循环

void main() {
  outerLoop:
  for (var i = 1; i <= 3; i++) {
    for (var j = 1; j <= 3; j++) {
      print('i = $i, j = $j');
      if (i == 2 && j == 2) {
        break outerLoop; // 直接终止外层outerLoop
      }
    }
  }
  print('outerLoop exited');
}
Code language: Dart (dart)

输出:

i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 2, j = 2
outerLoop exited
Code language: Dart (dart)

2. continue + label

直接进入外层下一轮

void main() {
  outerLoop:
  for (var i = 1; i <= 3; i++) {
    for (var j = 1; j <= 3; j++) {
      if (i == 2 && j == 2) {
        continue outerLoop; // 跳过当前i=2剩余所有j,直接i=3
      }
      print('i = $i, j = $j');
    }
  }
}
Code language: Dart (dart)

输出:

i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 3, j = 1
i = 3, j = 2
i = 3, j = 3

while+break+label

void main() {
  var i = 1;
  outerLoop:
  while (i <= 3) {
    var j = 1;
    while (j <= 3) {
      print('i = $i, j = $j');
      if (i == 2 && j == 2) {
        break outerLoop;
      }
      j++;
    }
    i++;
  }
  print('outerLoop exited');
}
Code language: PHP (php)

执行结果

D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 2, j = 2
outerLoop exited

和其他编程语言goto有点类型。

Previous:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注