一、標準 for 迴圈
語法:for(初始化; 條件; 迭代器) { 迴圈主體 }
1:基礎字串拼接
void main() {
var message = StringBuffer('welcome to FoxDevelop.com');
for (var i = 0; i < 5; i++) {
message.write('!');
}
print(message); // welcome to FoxDevelop.com!!!!!
}Code language: Dart (dart)
等同於從0迴圈到5(不含5),i 的值為0到4,總共執行五次;每次都在字串 welcome to FoxDevelop.com 尾端拼接驚嘆號!
第一次 welcome to FoxDevelop.com!
第二次 welcome to FoxDevelop.com!!
…
第五次 welcome to FoxDevelop.com!!!!!
特性:閉包獨立綁定索引(與 JS 重大差異)
Dart 每次迴圈都會綁定獨立的 i 變數,不會發生 JavaScript 全部輸出 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 搭配物件模式解構(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 原生內建方法,所有可迭代集合皆可呼叫。
四、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 區塊;若 isDone() 改為回傳 true,第一次判斷就不成立,區塊程式完全不會執行。
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
直接終止整個迴圈,跳至迴圈後方程式,後續剩餘程式不會執行。
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。
迴圈 Loops