前端学习-Dart官方文档学习-003-模式匹配
简介
匹配和解构
// 匹配
const a = 'a';
const b = 'b';
switch (obj) {
// List pattern [a, b] matches obj first if obj is a list with two fields,
// then if its fields match the constant subpatterns 'a' and 'b'.
case [a, b]:
print('$a, $b');
}
// 解构
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);
变量赋值
使用变量赋值模式交换两个变量的值,而不声明第三个临时变量:
var (a, b) = ('left', 'right');
(b, a) = (a, b); // Swap.
print('$a $b'); // Prints "right left".
Switch
switch (obj) {
// Matches if 1 == obj.
case 1:
print('one');
// Matches if the value of obj is between the
// constant values of 'first' and 'last'.
case >= first && <= last:
print('in range');
// Matches if obj is a record with two fields,
// then assigns the fields to 'a' and 'b'.
case (var a, var b):
print('a = $a, b = $b');
default:
}
// 逻辑或在switch比较常见
var isPrimary = switch (color) {
Color.red || Color.yellow || Color.blue => true,
_ => false
};
// Switch 中的条件
switch (pair) {
case (int a, int b):
if (a > b) print('First element greater');
// If false, prints nothing and exits the switch.
case (int a, int b) when a > b:
// If false, prints nothing but proceeds to next case.
print('First element greater');
case (int a, int b):
print('First element not greater');
}
For and for-in loops
Map<String, int> hist = {
'a': 23,
'b': 100,
};
for (var MapEntry(key: key, value: count) in hist.entries) {
print('$key occurred $count times');
}
key: key 可简写为 :key
for (var MapEntry(:key, value: count) in hist.entries) {
print('$key occurred $count times');
}
在 Dart 中,MapEntry是Map中的一个内部类,它表示Map中的一个键值对
Map<String, int> myMap = {
'a': 1,
'b': 2,
'c': 3,
};
// 获取 Map 中的第一个键值对
MapEntry<String, int> firstEntry = myMap.entries.first;
// 访问键和值
String key = firstEntry.key;
int value = firstEntry.value;
// 修改值
firstEntry.value = 4;
// 打印修改后的 Map
print(myMap);
Algebraic data types(没懂
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
};
Validating incoming JSON
当知道JSON结构时
var json = {
'user': ['Lily', 13]
};
var {'user': [name, age]} = json;
当JSON来自外部(如网络),需要先进行验证
// 普通写法
if (json is Map<String, Object?> &&
json.length == 1 &&
json.containsKey('user')) {
var user = json['user'];
if (user is List<Object> &&
user.length == 2 &&
user[0] is String &&
user[1] is int) {
var name = user[0] as String;
var age = user[1] as int;
print('User $name is $age years old.');
}
}
// pattern写法
if (json case {'user': [String name, int age]}) {
print('User $name is $age years old.');
}
Pattern types 模式匹配类型
优先级 precedence
- 低优先级:Logical-or < logical-and < relational
- 中优先级:cast(强制转换), null-check, and null-assert 优先级相同
- 高优先级:Collection-type (record, list, and map) and Object patterns
Logical-or < logical-and < relational
Logical-or
var isPrimary = switch (color) {
Color.red || Color.yellow || Color.blue => true,
_ => false
};
logical-and
Subpatterns in a logical-and pattern can bind variables, but the variables in each subpattern must not overlap, because they will both be bound if the pattern matches:
switch ((1, 2)) {
// Error, both subpatterns attempt to bind 'b'.
case (var a, var b) && (var b, var c): // ...
}
relational ==, !=, <, >, <=, and >=.
String asciiCharType(int char) {
const space = 32;
const zero = 48;
const nine = 57;
return switch (char) {
< space => 'control',
== space => 'space',
> space && < zero => 'punctuation',
>= zero && <= nine => 'digit',
_ => ''
};
}
cast(强制转换), null-check, and null-assert
cast(强制转换)
foo as String
(num, Object) record = (1, 's');
var (i as int, s as String) = record;
null-check
subpattern?
没太懂
String? maybeString = 'nullable with base type String';
switch (maybeString) {
case var s?:
// 's' has type non-nullable String here.
}
null-assert
subpattern!
(int?, int?) position = (2, 3);
var (x!, y!) = position;
Collection-type (record, list, and map) and Object patterns
list
[subpattern1, subpattern2]
const a = 'a';
const b = 'b';
switch (obj) {
// List pattern [a, b] matches obj first if obj is a list with two fields,
// then if its fields match the constant subpatterns 'a' and 'b'.
case [a, b]:
print('$a, $b');
}
// List patterns can contain one rest element (...) which allows matching lists of arbitrary lengths.
var [a, b, ..., c, d] = [1, 2, 3, 4, 5, 6, 7];
// Prints "1 2 6 7".
print('$a $b $c $d');
Map
{"key": subpattern1, someConst: subpattern2}
Record
(subpattern1, subpattern2)
(x: subpattern1, y: subpattern2)
var (myString: foo, myNumber: bar) = (myString: 'string', myNumber: 1);
// Record pattern with variable subpatterns:
var (untyped: untyped, typed: int typed) = record;
var (:untyped, :int typed) = record;
switch (record) {
case (untyped: var untyped, typed: int typed): // ...
case (:var untyped, :int typed): // ...
}
// Record pattern with null-check and null-assert subpatterns:
switch (record) {
case (checked: var checked?, asserted: var asserted!): // ...
case (:var checked?, :var asserted!): // ...
}
// Record pattern with cast subpattern:
var (untyped: untyped as int, typed: typed as String) = record;
var (:untyped as int, :typed as String) = record;
Object
SomeClass(x: subpattern1, y: subpattern2)
switch (shape) {
// Matches if shape is of type Rect, and then against the properties of Rect.
case Rect(width: var w, height: var h): // ...
}
通配符Wildcard _
通配符可以用于在类型注解中表示未知或不特定的类型。以下是一些常见的使用场景:
List<_> myList = [1, 2, 3]; // 在使用泛型时,通配符可以用于表示未知的类型参数
void myFunction(_ myParameter) {
// 通配符可以用于表示函数参数的类型不特定;在这里处理 myParameter
}
It's useful as a placeholder in places where you need a subpattern in order to destructure later positional values:
var list = [1, 2, 3];
var [_, two, _] = list;
A wildcard name with a type annotation is useful when you want to test a value's type but not bind the value to a name:
switch (record) {
case (int _, String _):
print('First field is int and second is String.');
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 易语言 —— 开山篇