dart-use-pattern-matching
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseImplementing Dart Patterns
Dart模式匹配实现
Contents
目录
Pattern Selection Strategy
模式选择策略
Apply specific pattern types based on the data structure and desired outcome. Follow these conditional guidelines:
- If validating and extracting from deserialized data (e.g., JSON): Use Map and List patterns to simultaneously check structure and destructure key-value pairs.
- If handling multiple return values: Use Record patterns to destructure fields directly into local variables.
- If executing type-specific behavior (Algebraic Data Types): Use Object patterns combined with classes to ensure exhaustiveness.
sealed - If matching numeric ranges or conditions: Use Relational (,
>=) and Logical-and (<=) patterns.&& - If multiple cases share logic: Use Logical-or () patterns to share a single case body or guard clause.
|| - If ignoring specific values: Use the Wildcard pattern () or a non-matching Rest element (
_) in collections....
根据数据结构和预期结果应用特定的模式类型。遵循以下条件准则:
- 如果要验证并从反序列化数据(如JSON)中提取内容: 使用Map和List模式,同时检查结构并解构键值对。
- 如果处理多个返回值: 使用Record模式将字段直接解构为局部变量。
- 如果执行特定类型的行为(代数数据类型): 将Object模式与类结合使用,以确保覆盖所有情况。
sealed - 如果匹配数值范围或条件: 使用关系(、
>=)和逻辑与(<=)模式。&& - 如果多个案例共享逻辑: 使用逻辑或()模式来共享单个案例体或守卫子句。
|| - 如果忽略特定值: 在集合中使用通配符模式()或不匹配的Rest元素(
_)。...
Switch Statements vs. Expressions
Switch语句与表达式
Select the appropriate switch construct based on the execution context:
- If producing a value: Use a switch expression.
- Syntax:
switch (value) { pattern => expression, } - Rule: Each case must be a single expression. No implicit fallthrough. Must be exhaustive.
- Syntax:
- If executing statements or side effects: Use a switch statement.
- Syntax:
switch (value) { case pattern: statements; } - Rule: Empty cases fall through to the next case. Non-empty cases implicitly break (no keyword required).
break
- Syntax:
根据执行上下文选择合适的switch结构:
- 如果要生成值: 使用switch表达式。
- 语法:
switch (value) { pattern => expression, } - 规则:每个案例必须是单个表达式。不允许隐式贯穿。必须覆盖所有情况。
- 语法:
- 如果要执行语句或副作用: 使用switch语句。
- 语法:
switch (value) { case pattern: statements; } - 规则:空案例会贯穿到下一个案例。非空案例会隐式中断(不需要关键字)。
break
- 语法:
Core Pattern Implementations
核心模式实现
Implement patterns using the following syntax and rules:
- Logical-or ():
||. Both branches must define the exact same set of variables.pattern1 || pattern2 - Logical-and ():
&&. Branches must not define overlapping variables.pattern1 && pattern2 - Relational: ,
==,!=,<,>,<=followed by a constant expression.>= - Cast ():
as. Throws if the value does not match the type. Use to forcibly assert types during destructuring.pattern as Type - Null-check ():
?. Fails the match if the value is null. Binds the variable to the non-nullable base type.pattern? - Null-assert ():
!. Throws if the value is null.pattern! - Variable: or
var name. Binds the matched value to a new local variable.Type name - Wildcard (): Matches any value and discards it.
_ - List: . Matches lists of exact length unless a Rest element (
[pattern1, pattern2]or...) is used....var rest - Map: . Matches maps containing the specified keys. Ignores unmatched keys.
{"key": pattern} - Record: . Matches records of the exact shape. Use
(pattern1, named: pattern2)to infer the getter name.:var name - Object: . Matches instances of
ClassName(field: pattern). UseClassNameto infer the getter name.:var field
使用以下语法和规则实现模式:
- 逻辑或():
||。两个分支必须定义完全相同的变量集。pattern1 || pattern2 - 逻辑与():
&&。分支不得定义重叠变量。pattern1 && pattern2 - 关系模式: 、
==、!=、<、>、<=后跟常量表达式。>= - 类型转换():
as。如果值与类型不匹配则抛出异常。用于在解构期间强制断言类型。pattern as Type - 空检查():
?。如果值为null则匹配失败。将变量绑定到非空基础类型。pattern? - 空断言():
!。如果值为null则抛出异常。pattern! - 变量模式: 或
var name。将匹配的值绑定到新的局部变量。Type name - 通配符(): 匹配任何值并将其丢弃。
_ - List模式: 。匹配精确长度的列表,除非使用Rest元素(
[pattern1, pattern2]或...)。...var rest - Map模式: 。匹配包含指定键的Map。忽略不匹配的键。
{"key": pattern} - Record模式: 。匹配精确结构的Record。使用
(pattern1, named: pattern2)来推断getter名称。:var name - Object模式: 。匹配
ClassName(field: pattern)的实例。使用ClassName来推断getter名称。:var field
Workflows
工作流程
Task Progress: Implementing Pattern Matching
任务进度:实现模式匹配
Copy this checklist to track progress when implementing complex pattern matching logic:
- Identify the data structure being evaluated (JSON, Record, Class, Enum).
- Select the appropriate switch construct (Expression for values, Statement for side-effects).
- Define the required patterns (Object, Map, List, Record).
- Extract required data using Variable patterns (,
var x).:var y - Apply Guard clauses () for logic that cannot be expressed via patterns.
when condition - Handle unmatched cases using a Wildcard () or
_clause (if not using a sealed class).default - Run exhaustiveness validator.
复制此检查表以跟踪实现复杂模式匹配逻辑的进度:
- 确定要评估的数据结构(JSON、Record、Class、Enum)。
- 选择合适的switch结构(生成值用表达式,执行副作用用语句)。
- 定义所需的模式(Object、Map、List、Record)。
- 使用变量模式(、
var x)提取所需数据。:var y - 应用守卫子句()处理无法通过模式表达的逻辑。
when condition - 使用通配符()或
_子句处理未匹配的案例(如果未使用sealed类)。default - 运行完备性验证器。
Feedback Loop: Exhaustiveness Checking
反馈循环:完备性检查
When switching over classes or enums, you must ensure all subtypes are handled.
sealed- Run validator: Execute .
dart analyze - Review errors: Look for "The type 'X' is not exhaustively matched by the switch cases" errors.
- Fix: Add the missing Object patterns for the unhandled subtypes, or add a Wildcard () case if a default fallback is acceptable.
_
当对类或枚举进行switch操作时,必须确保处理所有子类型。
sealed- 运行验证器: 执行。
dart analyze - 查看错误: 查找"The type 'X' is not exhaustively matched by the switch cases"(类型'X'未被switch案例完全匹配)错误。
- 修复: 为未处理的子类型添加缺失的Object模式,或者如果可以接受默认回退,则添加通配符()案例。
_
Examples
示例
JSON Validation and Destructuring
JSON验证与解构
Use Map and List patterns to validate structure and extract data in a single step.
Input:
dart
var data = {
'user': ['Lily', 13],
};Implementation:
dart
if (data case {'user': [String name, int age]}) {
print('User $name is $age years old.');
} else {
print('Invalid JSON structure.');
}使用Map和List模式在单个步骤中验证结构并提取数据。
输入:
dart
var data = {
'user': ['Lily', 13],
};实现:
dart
if (data case {'user': [String name, int age]}) {
print('User $name is $age years old.');
} else {
print('Invalid JSON structure.');
}Algebraic Data Types (Sealed Classes)
代数数据类型(密封类)
Use Object patterns with switch expressions to handle family types exhaustively.
Implementation:
dart
sealed class Shape {}
class Square implements Shape {
final double length;
Square(this.length);
}
class Circle implements Shape {
final double radius;
Circle(this.radius);
}
// Switch expression guarantees exhaustiveness due to `sealed` modifier.
double calculateArea(Shape shape) => switch (shape) {
Square(length: var l) => l * l,
Circle(:var radius) => math.pi * radius * radius,
};将Object模式与switch表达式结合使用,以全面处理家族类型。
实现:
dart
sealed class Shape {}
class Square implements Shape {
final double length;
Square(this.length);
}
class Circle implements Shape {
final double radius;
Circle(this.radius);
}
// 由于`sealed`修饰符,switch表达式保证覆盖所有情况。
double calculateArea(Shape shape) => switch (shape) {
Square(length: var l) => l * l,
Circle(:var radius) => math.pi * radius * radius,
};Variable Swapping and Destructuring
变量交换与解构
Use variable assignment patterns to swap values or extract record fields without temporary variables.
Implementation:
dart
var (a, b) = ('left', 'right');
(b, a) = (a, b); // Swap values
// Destructuring a function return
var (name, age) = getUserInfo(); 使用变量赋值模式交换值或提取Record字段,无需临时变量。
实现:
dart
var (a, b) = ('left', 'right');
(b, a) = (a, b); // 交换值
// 解构函数返回值
var (name, age) = getUserInfo(); Guard Clauses and Logical-or
守卫子句与逻辑或
Use to evaluate arbitrary conditions after a pattern matches.
whenImplementation:
dart
switch (shape) {
case Square(size: var s) || Circle(size: var s) when s > 0:
print('Valid symmetric shape with size $s');
case Square() || Circle():
print('Invalid or empty shape');
default:
print('Unknown shape');
}使用在模式匹配后评估任意条件。
when实现:
dart
switch (shape) {
case Square(size: var s) || Circle(size: var s) when s > 0:
print('Valid symmetric shape with size $s');
case Square() || Circle():
print('Invalid or empty shape');
default:
print('Unknown shape');
}