概要
- Matching data (匹配数据)
- Destructuring Data (解构)
模式匹配(Match Patterns)是一种很好用的语法,不同于普通匹配的比较值, 指针, hashcode && eqaul, 基于这些基本的匹配,有一个新增的类型叫做Record. 之后再详细分析Record的原理, 我们继续看模式匹配.
// 我们声明了一个Record,按顺序记录了三个值。
(int, String, {bool isValid}) triple = (1, "one", isValid: true);
// 进行模式匹配
switch (triple) {
// Destructuring, 并匹配出isValid = true的情况
case (int value, String name, isValid: bool ok):
break;
}
基础用法
- 解构
// 解构变量,var 表示可变,final表示不可变
var (String name, Color color) = ("Rose", Colors.red);
final (String name, Color color) = ("Rose", Colors.red);
// 解构数组
var numList = [1, 2, 3];
// List pattern [a, b, c] destructures the three elements from numList...
var [a, b, c] = numList;
// ...and assigns them to new variables.
print(a + b + c);
// 解构map
Map<String, int> hist = {
'a': 23,
'b': 100,
};
for (var MapEntry(key: key, value: count) in hist.entries) {
print('$key occurred $count times');
}
进阶用法
- 解构
// 函数多个返回值
var (name, age) = userInfo(json);
// 解构对象
final Foo myFoo = Foo(one: 'one', two: 2);
var Foo(:one, :two) = myFoo;
print('one $one, two $two');
// json校验
var json = {
'user': ['Lily', 13]
};
var {'user': [name, age]} = json;
if (json case {'user': [String name, int age]}) {
print('User $name is $age years old.');
}
// 代数类型
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
};
// switch
switch (obj) {
// Matches if 1 == obj.
case 1:
print('one');
case >= first && <= last:
print('in range');
// 解构并匹配
case (var a, var b):
print('a = $a, b = $b');
default:
}
// gurad, 针对所有前置
switch (shape) {
case Square(size: var s) || Circle(size: var s) when s > 0:
print('Non-empty symmetric shape');
}
底层支持
- Record类型,在其他语言中的类似概念称为(元组),这个类被声明在
sky/engine/core, 从注释和代码当中我们可以看到Record是有类型的,并且All objects that implement Record has a record type as their runtime type., 所有实现了Record类型都有自己的runtimeType,。
abstract final class Record {
// (int, String, {bool isValid}), 声明即是Record的runtimeType.
Type get runtimeType;
// (int,) one = (1,);
// (int,) two = (1,);
// assert(one.hashCode == two.hashCode);
int get hashCode;
// (String,) one = ("a",);
// (String,) two = ("b",);
// one == two // false
print(one == two);
bool operator ==(Object other);
String toString();
}