一、if / if-else 基礎分支
if括號內必須放置布林運算式,不允許自動隱式轉換布林值- 支援多個
else if區塊,末尾可選擇性加上else - 單行程式碼可省略大括號,但建議一律加上大括號提升可讀性
void main() {
bool isRaining = false;
bool isSnowing = true;
if (isRaining) {
print("帶雨衣");
} else if (isSnowing) {
print("穿厚外套");
} else {
print("開敞篷車");
}
}Code language: Dart (dart)
執行結果
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
穿厚外套Code language: CSS (css)
也可以單獨使用 if
void main() {
bool isRaining = false;
bool isSnowing = true;
if (isRaining) {
print("帶雨衣");
}
}Code language: Dart (dart)
或是僅使用 if else
void main() {
bool isRaining = false;
bool isSnowing = true;
if (isRaining) {
print("帶雨衣");
} else {
print("開敞篷車");
}
}Code language: Dart (dart)
二、if-case 模式比對分支(Dart3.0 以上適用)
- 進行模式比對,比對成功時會解構綁定變數至當前作用域
- 比對失敗會進入 else;可搭配
when守衛新增布林判斷條件 - 僅適用於單一值配單一模式場景,多模式比對請改用 switch
void main() {
final pair = [100, 220];
// 比對長度為2、內含兩個整數的陣列
if (pair case [int x, int y]) {
print("座標:$x,$y");
} else {
throw FormatException("無效座標");
}
}Code language: Dart (dart)
執行結果
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
座標:10,20Code language: CSS (css)
2:搭配 when 守衛的 if-case
void main() {
final data = [8, 9];
if (data case [int a, int b] when a > 5 && b > 5) {
print("兩個數字皆大於5");
} else {
print("數字未符合條件");
}
}Code language: Dart (dart)
執行結果
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
兩個數字皆大於5Code language: CSS (css)
三、switch 陳述式
傳統 switch 為陳述式語法,沒有回傳值
- case 支援各種模式:字串、常數、邏輯或、關係運算模式
- 有內容的 case 會自動中斷,不需手動撰寫 break;空 case 會自動穿透往下執行
- 手動實現穿透有兩種方式:
continue 標籤或是連續撰寫空 case - 所有 case 皆不匹配時執行
default;同樣支援when守衛
1:基礎字串比對範例
void main() {
String command = "OPEN";
switch (command) {
case "CLOSED":
print("執行關閉邏輯");
case "PENDING":
print("執行等待邏輯");
case "OPEN":
print("執行開啟邏輯");
default:
print("未知指令");
}
}
Code language: Dart (dart)
執行結果
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
執行開啟邏輯Code language: CSS (css)
2:空 case 穿透 + continue 標籤跳轉
String command = "OPEN";
switch (command) {
case "OPEN":
print("開啟操作"); // ① 匹配 OPEN 並執行列印
continue newCase; // ② 直接跳至 newCase 標記處,不再回溯判斷
case "DENIED":
case "CLOSED":
print("關閉操作");
newCase: // ③ 跳轉目標標籤
case "PENDING":
print("待處理統一邏輯"); // ④ 直接執行,不會再次判斷 command 是否等於 "PENDING"
}Code language: Dart (dart)
執行結果
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
開啟操作
待處理統一邏輯Code language: CSS (css)
不少讀者會疑惑:範例中
continue newCase;確實跳轉到 newCase 標籤,但後面 case “PENDING” 根本不會匹配,為什麼還是會執行 print(“待處理統一邏輯”);?這是大部分初學者都會有的疑問
continue 標籤; 不會重新比對值,而是直接跳轉到標籤所屬 case 分支的開頭,跳過所有條件判斷,立刻執行分支內程式碼。
3:switch 搭配 when 守衛
void main() {
int score = 88;
switch (score) {
case int s when s >= 90:
print("優秀");
case int s when s >= 60:
print("及格");
default:
print("不及格");
}
}
Code language: Dart (dart)
輸出及格
程式會先比對型別,確認輸入為整數後將值賦予變數 s,接著透過 when 守衛做二次檢驗,只有 s 符合 when 後的條件才會執行該 case 內程式。這裡兩處 int s 雖然寫法相同,但各自作用域獨立、互不影響。
每一段 case int s 都是獨立的模式綁定,變數作用域僅限於自身 case 分支,不會互相干擾
你完全可以替兩個 case 使用不同變數名稱,執行效果完全一致。
switch (score) {
case int a when a >= 90:
print("優秀");
case int b when b >= 60:
print("及格");
default:
print("不及格");
}Code language: Dart (dart)
四、switch 運算式
Dart3.0 以上才支援的語法,具備回傳值,常用於變數賦值
與 switch 陳述式差異
- 不需
case關鍵字,以=>分隔模式與回傳運算式 - 每個分支必須回傳運算式,多分支使用逗號隔開
- 無隱式穿透,各分支獨立;無任何匹配時使用底線符
_作兜底,不能使用 default - 可直接用於賦值、列印、函式回傳,適用所有運算式場景
1:基礎字元運算子比對(邏輯或模式)
void main() {
const slash = 47, star = 42, comma = 44;
int charCode = 42;
final token = switch (charCode) {
slash || star => "運算子",
comma => "標點符號",
_ => "無效字元"
};
print(token);
}
Code language: Dart (dart)
執行結果
運算子
本範例定義三個符號 ASCII 碼常數,透過 charCode 變數判斷當前字元屬於運算子、標點符號或其他無效符號。
2:switch 運算式搭配 when 守衛
void main() {
int age = 22;
String level = switch (age) {
int a when a < 18 => "未成年",
int a when a < 30 => "青年",
_ => "成年"
};
print(level);
}Code language: Dart (dart)
執行結果
青年
3:函式回傳直接使用 switch 運算式
void main() {
print(getDesc(3));
}
String getDesc(int num) => switch (num) {
1 => "一",
2 => "二",
_ => "其他數字"
};
Code language: Dart (dart)
執行結果
其他數字
注意:此處 switch 屬於運算式,而 getDesc 是箭頭函式;箭頭函式是 Dart 相較其他 C 系列語言獨有的語法。
五、窮舉檢查 Exhaustiveness Checking
若輸入值存在未覆蓋的匹配分支會觸發編譯錯誤,強制開發者補全所有 case;密封類 sealed、列舉 enum 原生支援窮舉檢查,不需額外 _ / default 兜底。
1:可空布林值觸發非窮舉錯誤(可註解執行觀察錯誤訊息)
void main() {
bool? nullableBool = null;
// 取消下方程式註解會報編譯錯誤:缺少 null 匹配分支,且無 _ / default 兜底
/*
switch (nullableBool) {
case true:
print("是");
case false:
print("否");
}
*/
// 修正方式:新增 null 分支或是底線符 _ 兜底
switch (nullableBool) {
case true:
print("是");
case false:
print("否");
case null:
print("空值");
}
}Code language: PHP (php)
執行結果
空值
2:sealed 密封類
代數資料型別,強制開發者完成所有分支窮舉匹配
import 'dart:math' as math;
// 密封類:僅能在同一個檔案內實作子類別
sealed class Shape {}
// 子類別 方形:邊長參數
class Square implements Shape {
final double length;
Square(this.length);
}
//子類別 圓形:半徑參數
class Circle implements Shape {
final double radius;
Circle(this.radius);
}
//箭頭函式,依傳入子類物件透過 switch 匹配計算面積
double calculateArea(Shape shape) => switch (shape) {
Square(length: var l) => l * l,
Circle(radius: var r) => math.pi * r * r
// 新增 Shape 子類別會直接報編譯錯誤,提示缺少對應 case
};
void main() {
final Shape circle = Circle(5);
print(calculateArea(circle));
final Shape square = Square(4);
print(calculateArea(square));
}
Code language: Dart (dart)
執行結果
78.53981633974483
16.0Code language: CSS (css)
3:Enum 列舉窮舉匹配
不需要底線_兜底
void main() {
final Animal animal = Animal.cat;
String name = switch (animal) {
Animal.dog => "小狗",
Animal.cat => "小貓"
};
print(name);
}
enum Animal { dog, cat }
Code language: Dart (dart)
輸出:小貓
enum 列舉的值範圍固定,不會出現額外未知值,因此不需設定兜底分支。
六、when 守衛
完整支援 if-case /switch 陳述式 /switch 運算式三種語法
when 作用:模式匹配成功後追加布林判斷;若守衛判斷為 false,會進入下一個分支,不會直接離開 switch。
1. if-case + when
void main() {
List<int> arr = [10, 20];
if (arr case [int x, int y] when x + y > 20) {
print("兩數相加大於20");
}
}Code language: Dart (dart)
兩數相加大於20
程式先驗證型別是否為兩個整數的陣列,符合條件後再透過 when 判斷兩數總和是否大於20
2. switch 陳述式 + when
void main() {
int num = 15;
switch(num) {
case int n when n % 2 == 0:
print("偶數");
case int n when n % 2 != 0:
print("奇數");
}
}
Code language: PHP (php)
輸出:奇數
先判斷輸入是否為整數,接著執行 when 內的條件判斷。
3. switch 運算式 + when
void main() {
int num = 15;
String res = switch(num) {
int n when n % 2 == 0 => "偶數",
_ => "奇數"
};
print(res);
}
Code language: PHP (php)