dart-language-syntax
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesedart-advanced-syntax-and-patterns
Dart高级语法与模式
Goal
目标
Implements idiomatic Dart code leveraging advanced syntax, including pattern matching, records, generics, and sound null safety, to produce robust, type-safe, and concise applications. This skill assumes a Dart 3.0+ environment and focuses on applying modern language features to optimize data structures, control flow, and API design.
实现符合Dart惯用风格的代码,利用高级语法(包括模式匹配、records、泛型和健全空安全)来打造健壮、类型安全且简洁的应用。本技能假设使用Dart 3.0+环境,重点在于应用现代语言特性优化数据结构、控制流和API设计。
Instructions
说明
-
Variable Declaration and Null Safety Apply sound null safety and strict mutability rules when declaring variables.
- Use for local variables with obvious types.
var - Use for variables that should not be reassigned.
final - Use for compile-time constants.
const - Use only when control flow analysis fails to detect initialization, or for expensive lazy initialization.
late - Use wildcard variables for non-binding placeholders (requires Dart 3.7+).
_
dartfinal name = 'Bob'; // Immutable var count = 0; // Obvious type late final String expensiveResult = computeExpensiveValue(); // Wildcard usage for (var _ in list) { print('Iterating without binding'); } - Use
-
Function Design and Tear-offs Structure functions using named parameters, optional positional parameters, and tear-offs for concise callbacks.
- Use for mandatory named parameters.
required - Prefer tear-offs over lambdas when passing functions directly.
dart// Named parameters with required and default values void configure({required String id, bool verbose = false}) { ... } // Tear-offs final charCodes = [68, 97, 114, 116]; final buffer = StringBuffer(); charCodes.forEach(buffer.write); // Method tear-off - Use
-
Implementing Records for Multiple Returns Use recordsto return multiple values without defining a dedicated class.
(...)dart// Returning a record (String, int) fetchUserInfo(Map<String, dynamic> json) { return (json['name'] as String, json['age'] as int); } // Returning a record with named fields ({String name, int age}) fetchNamedUserInfo() { return (name: 'Dash', age: 10); } -
Pattern Matching and Destructuring (Decision Logic) Master pattern matching in assignments, switch statements, and JSON validation. Follow this decision logic when handling complex data:
- If extracting values from a record or collection: Use variable assignment/declaration patterns.
- If branching logic based on object shape or type: Use expressions with pattern matching and guard clauses (
switch).when - If validating external data (e.g., JSON): Use statements with map/list patterns.
if-case
dart// Destructuring a record var (name, age) = fetchUserInfo(json); // Switch expression with algebraic data types and guards double calculateArea(Shape shape) => switch (shape) { Square(length: final l) when l > 0 => l * l, Circle(radius: final r) => math.pi * r * r, _ => throw ArgumentError('Invalid shape'), }; // JSON Validation using if-case if (json case {'user': [String name, int age]}) { print('User $name is $age years old.'); } else { // Handle invalid JSON structure } -
Generics and Type Safety Implement genericsto ensure type safety in reusable components. Apply bounds (
<T>) to restrict parameterized types.extendsdart// Restricting to non-nullable types class Cache<T extends Object> { final Map<String, T> _storage = {}; T? getByKey(String key) => _storage[key]; void setByKey(String key, T value) => _storage[key] = value; } // Generic method T first<T>(List<T> items) { if (items.isEmpty) throw StateError('No elements'); return items[0]; } -
Extension Methods and Types Use extension methods and types to add functionality to existing classes or to create zero-cost abstractions over records/types.dart
extension type ButtonItem._(({String label, void Function() onPressed}) _) { ButtonItem({required String label, required void Function() onPressed}) : this._((label: label, onPressed: onPressed)); String get label => _.label; void Function() get onPressed => _.onPressed; } -
Validate and Fix After generating Dart code, verify that:
- No null dereference errors are possible.
- Records are used instead of custom classes for simple data tuples.
- Pattern matching is used for JSON validation instead of verbose checks.
is - STOP AND ASK THE USER: If the data structure shape for pattern matching is ambiguous or not provided, pause and ask the user for the expected JSON/Object schema before writing the destructuring logic.
-
变量声明与空安全 声明变量时应用健全空安全和严格可变性规则。
- 对于类型明显的局部变量,使用。
var - 对于不应被重新赋值的变量,使用。
final - 对于编译时常量,使用。
const - 仅当控制流分析无法检测到初始化,或用于代价高昂的延迟初始化时,使用。
late - 对于非绑定占位符,使用通配符变量(需要Dart 3.7+)。
_
dartfinal name = 'Bob'; // 不可变 var count = 0; // 类型明显 late final String expensiveResult = computeExpensiveValue(); // 通配符用法 for (var _ in list) { print('Iterating without binding'); } - 对于类型明显的局部变量,使用
-
函数设计与方法提取(Tear-offs) 使用命名参数、可选位置参数和方法提取来构建简洁的回调函数。
- 对于必填命名参数,使用。
required - 直接传递函数时,优先使用方法提取而非lambda表达式。
dart// 带有必填参数和默认值的命名参数 void configure({required String id, bool verbose = false}) { ... } // 方法提取 final charCodes = [68, 97, 114, 116]; final buffer = StringBuffer(); charCodes.forEach(buffer.write); // 方法提取 - 对于必填命名参数,使用
-
使用Records实现多返回值 使用records来返回多个值,无需定义专用类。
(...)dart// 返回record (String, int) fetchUserInfo(Map<String, dynamic> json) { return (json['name'] as String, json['age'] as int); } // 返回带命名字段的record ({String name, int age}) fetchNamedUserInfo() { return (name: 'Dash', age: 10); } -
模式匹配与解构(决策逻辑) 掌握在赋值、switch语句和JSON验证中的模式匹配。处理复杂数据时遵循以下决策逻辑:
- 如果从record或集合中提取值: 使用变量赋值/声明模式。
- 如果基于对象形状或类型进行分支逻辑: 使用带有模式匹配和守卫子句()的
when表达式。switch - 如果验证外部数据(如JSON): 使用带有映射/列表模式的语句。
if-case
dart// 解构record var (name, age) = fetchUserInfo(json); // 带有代数数据类型和守卫的switch表达式 double calculateArea(Shape shape) => switch (shape) { Square(length: final l) when l > 0 => l * l, Circle(radius: final r) => math.pi * r * r, _ => throw ArgumentError('Invalid shape'), }; // 使用if-case进行JSON验证 if (json case {'user': [String name, int age]}) { print('User $name is $age years old.'); } else { // 处理无效JSON结构 } -
泛型与类型安全 实现泛型以确保可复用组件的类型安全。应用边界约束(
<T>)来限制参数化类型。extendsdart// 限制为非空类型 class Cache<T extends Object> { final Map<String, T> _storage = {}; T? getByKey(String key) => _storage[key]; void setByKey(String key, T value) => _storage[key] = value; } // 泛型方法 T first<T>(List<T> items) { if (items.isEmpty) throw StateError('No elements'); return items[0]; } -
扩展方法与类型 使用扩展方法和类型为现有类添加功能,或为records/类型创建零开销抽象。dart
extension type ButtonItem._(({String label, void Function() onPressed}) _) { ButtonItem({required String label, required void Function() onPressed}) : this._((label: label, onPressed: onPressed)); String get label => _.label; void Function() get onPressed => _.onPressed; } -
验证与修复 生成Dart代码后,验证以下内容:
- 不存在可能的空引用错误。
- 对于简单数据元组,使用records而非自定义类。
- 使用模式匹配进行JSON验证,而非冗长的检查。
is - 停止并询问用户: 如果模式匹配的数据结构形状不明确或未提供,请暂停并向用户询问预期的JSON/对象架构,再编写解构逻辑。
Constraints
约束条件
- DO NOT use if the assigned type is not immediately obvious to the reader; use explicit types instead.
var - DO NOT use unless explicitly interacting with untyped external APIs (and immediately cast/validate it using patterns).
dynamic - DO NOT define a class just to return multiple values from a function; strictly use records.
- DO NOT use multiple underscores (,
__) for unused variables; use the single wildcard___._ - DO NOT wrap tear-offs in anonymous functions (e.g., avoid ; use
list.forEach((e) => print(e))).list.forEach(print) - DO NOT use checks and manual casting for JSON validation; strictly use
ispattern matching.if-case - Related Skills: .
dart-idiomatic-usage
- 如果赋值的类型对读者而言不明显,请勿使用;请改用显式类型。
var - 除非明确与无类型外部API交互(并立即使用模式进行转换/验证),否则请勿使用。
dynamic - 不要仅仅为了从函数返回多个值而定义类;严格使用records。
- 不要为未使用的变量使用多个下划线(,
__);请使用单个通配符___。_ - 不要将方法提取包装在匿名函数中(例如,避免;请使用
list.forEach((e) => print(e)))。list.forEach(print) - 不要使用检查和手动转换进行JSON验证;严格使用
is模式匹配。if-case - 相关技能:。
dart-idiomatic-usage