前言
模式匹配与模式的解构,主要用于记录类型(Records)的匹配与读取元素的值。延伸到其他的集合类型也可以使用模式匹配与模式解构。使用switch-case语句、if-case语句、switch表达式进行模式匹配与模式解构。
简单示例: 下面示例展示了不带命名参数的Records数据与带命名参数的Records数据,在模式匹配与模式解构的用法。
void main(){
final person = ('小明', 18); // 不带命名参数
final person1 = (name: '小王', age: 18); // 带命名参数
// 直接读取
print('姓名:${person.$1}, 年龄:${person.$2}');
// 模式解构
caseTest(person); //输出: 不带命名参数 姓名:小明 年龄:18
caseTest(person1); //输出:带命名参数 姓名:小王 年龄:18
}
void caseTest(Object value) {
switch(value) {
case (String name, int age):
print('不带命名参数 姓名:$name 年龄: $age');
// 也可以用 case (name: String name, age: int age)
case (:String name, :int age):
print('带命名参数 姓名:$name1 年龄:$age');
}
}
模式匹配
模式匹配分为:
- 匹配值
- 匹配类型
1、匹配值
- 完全匹配 所有的数据的值相等
final person = ('小明',18);
/// 匹配完整的值 switch-case语句
switch (person) {
case ('小明', 18):
print('匹配成功');
}
/// 匹配完整的值 if-case语句
if (person case ('小明', 18)) {
print('匹配成功');
}
- 部分匹配(忽略某个值的匹配)
final person = ('小明',18);
/// switch-case
switch (person) {
case (_, 18):
print('匹配年龄为18的人');
}
- 匹配某个值可多选
final person = ('小明',18);
switch (person) {
case ('小明' || '小王', 18):
print('小明 和 小王,年龄为18岁');
}
2、匹配类型
一般用is判断类型,这里只需要知道,还能进行类型的判断。
final person = ('小明', 18);
switch(person) {
case (String _, int _):
print('匹配类型成功');
}
/// 当然这里类型判断可以用is进行判断
if (person is (String, int)) {
print('类型匹配成功');
}
模式解构
模式解构分为:
- 声明时解构
- 匹配时解构
1、声明时解构
final (name, age) = ('小明', 18);
// or
final (name: name,age: age) = (name: '小明', age: 18);
// or
final (:name, :age) = (name: '小明', age: 18);
2、匹配时解构
- 不带命名参数的Records解构
final person = ('小明', 18);
switch (person) {
case (String name, int age):
print('name:${name} age:$age');
}
- 带命名参数的Records解构
final person = (name: '小明', age: 18);
switch (person) {
case (:String name, :int age):
print('name:${name} age:$age');
}
- Map类型数据解构
final person = {'name': '小明', 'age': 18};
switch (person) {
case {'name': String name, 'age': int age}:
print('name:${name} age:$age');
}
带条件的模式匹配
switch (shape) {
case Square(size: var s) || Circle(size: var s) when s > 0:
print('Non-empty symmetric shape');
}
最佳实践
- 解决多层嵌套
void validData(bool b1, bool b2, bool b3) {
final data = (b1, b2, b3);
switch (data) {
case (true,true,true):
print('全部通过');
case (true, true, false):
print('条件3未通过');
case (true, false, true):
print('条件2未通过');
case (true, false, false):
print('条件2未通过,条件3未通过');
default:
print('默认处理');
}
}
- 利用完备性检查,实现枚举类
sealed class Shape {}
class Square implements Shape {
final double length;
Square(this.length);
}
class Circle implements Shape {
final double radius;
Circle(this.radius);
}
double calculateArea(Shape shape) => switch (shape) {
Square(length: var l) => l * l,
Circle(radius: var r) => math.pi * r * r
};