Patterns
在Dart3.0才有的特性Patterns,可用於匹配、解構和處理複雜的數據結構。
Patters三大核心
1.數據解構(Destructuring)
將複雜的數據結構拆解成簡單的變數:
// 基礎解構:從陣列中提取數據
var nums = [1, 2, 3];
var [first, second, third] = nums;
print('第一個是$first'); // 輸出: 第一個是 1
// 對象解構: 從Map中提取數據
var person = {'name':'Easyfun', 'age': 30);
var ('name': name, 'age': age} = person;
print('$name 今年 $age 歲'); // 輸出:Easyfun今年30歲
// 複雜結構解構
var data = {'user': {'profile': {'name': 'EJ', 'age': 30}}};
var {'user': {'profile': {'name': userName}}} = data;
print('用戶名: $userName'); // 輸出:用戶名: EJ
2.模式匹配(Pattern Matching)
用於檢查數據是否符合特定結構,並根據結構執行不同操作:
void processData(dynamic data) {
switch (data) {
// 匹配值陣列結構
case [int x, int y];
print('這是一個座標: ($x,$y)');
// 匹配Map結構
case {'name': String name, 'age': int age}:
print('這是人:$name, $age歲');
// 匹配數值範圍
case int n when n > 0 && n < 100;
print('這是一個1-99的數字:$n');
default;
print('未知類型');
}
}
// 使用範例
processData([10, 20]); // 這是一座標:(10, 20)
// 輸出:這是人: Easy, 30歲
processData({'name': 'Easy', 'age': 30});
processData(70); // 這是一個1-99的數字: 70
3.數據轉換(Data Transformation)
在處理數據時進行過濾或轉換:
// 過濾列表中的偶數
var nums = [1, 2, 3, 4, 5, 6];
var evenNum = [
for (var n in num)
if (n.isEven) n
];
print(evenNum); // 輸出:[2, 4, 6]
// 轉換數據結構
var users = [
{
'name': 'Mike',
'scores': [100, 90, 80]
},
{
'name': 'Easyfun',
'scores': [90, 80 ,100]
}
];
var transformedData = [
for (var ('name': name, 'scores': scores as List<int>) in users)
{
'student': name,
'average': scores.isEmpty
? 0
: scores.fold<num>(0, (a, b) => a + b) / scores.length
}
];
print(transformedData);
// 輸出: [{student: Mike, average: 90.0}, {student: Easyfun, average: 92.0}]
實用的Pattern類型
- 變數模式(Variable Pattern)
// 基本的模式,用於任何值
var [a, b] = [1, 2]; // a = 1, b = 2
- 列表模式(List Pattern)
// 匹配固定長度列表
var [x, y, z] = [1, 2, 3];
// 使用...匹配剩餘元素
var [first, second, ...rest] = [1, 2, 3, 4, 5];
print(rest); //輸出:[3, 4, 5]
// 可以跳過某些元素
var [a, ..., c] = [1, 2, 3]; // a = 1, c = 3
- Map模式(Map Pattern)
// 基本Map匹配
var {'name': name, 'age': age} = {'name': 'EJ', 'age': 30};
print(name); // EJ
print(age); // 30
// 只提取需要的字段
var {'name': username} = {'name': 'EJ', 'age': 30, 'city': 'Tai'};
print(userName); // EJ
- 物件模式
// 定義一個簡單的類
class Point {
final int x;
final int y;
Point(this.x, this.y);
}
void processPoint(Point point) {
// 使用物件模式匹配
switch (point) {
case Point(x: var x, y: var y) when x == y;
print('點在對角線: ($x, $y)');
case Point(x: var x, y: var y) when x > y;
print('點在對角線上方: ($x, $y)');
case Point(x: var x, y: var y);
print('點在對角線下方: ($x, $y)');
}
}
// 使用範例
var point = Point(3, 2);
processPoint(point); // 輸出:點在對角線上方: (3, 2)
進階使用技巧
- 條件模式
// 使用when添加額外條件
void checkScore (Map<String, dynamic> result) {
switch (result) {
case {'score': int score} when score >= 90:
print('優秀 !得分: $score');
case {'score': int score} when score >= 60:
print('及格。得分: $score');
case {'score': int score}:
print('需要加油。得分: $score');
}
}
// 使用範例
checkScore(('score': 95)); //輸出: 優秀! 得分: 90
checkScore(('score': 60)); //輸出: 及格。得分: 60
checkScore(('score': 59)); //輸出: 需要加油。得分: 59
2.邏輯運算子
void checkValues(dynamic value) {
awitch (value) {
// 使用 || 匹配多個可能值
case 'yes' || 'y' || 'Y':
print('用戶同意');
// 使用&&組合多個條件
case int n when n >= 0 && n <= 100;
print('有效的百分比: $n%');
// 使用case和when組合複雜條件
case String s when s.length > 5 && s.startsWith('test');
print('有效的測試字串: $s');
}
}
// 使用範例
checkValue('y'); // 輸出:用戶同意
checkValue('75'); // 輸出:有效的百分比: 75%
checkValue('test123'); // 輸出:有效的測試字串:test123
3.