dart-modern-features
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDart Modern Features
Dart 现代特性
1. When to use this skill
1. 何时使用本技能
Use this skill when:
- Writing or reviewing Dart code targeting Dart 3.0 or later.
- Refactoring legacy Dart code to use modern, concise, and safe features.
- Looking for idiomatic ways to handle multiple return values, deep data extraction, or exhaustive checking.
在以下场景使用本技能:
- 编写或审查基于Dart 3.0及以上版本的代码时。
- 重构旧版Dart代码以使用现代、简洁且安全的特性时。
- 寻找处理多返回值、深度数据提取或穷尽检查的惯用方法时。
2. Features
2. 特性介绍
Records
Records
Use records as anonymous, immutable, aggregate structures to bundle multiple
objects without defining a custom class. Prefer them for returning multiple
values from a function or grouping related data temporarily.
Avoid:
Creating a dedicated class for simple multiple-value returns.
dart
class UserResult {
final String name;
final int age;
UserResult(this.name, this.age);
}
UserResult fetchUser() {
return UserResult('Alice', 42);
}Prefer:
Using records to bundle types seamlessly on the fly.
dart
(String, int) fetchUser() {
return ('Alice', 42);
}
void main() {
var user = fetchUser();
print(user.$1); // Alice
}使用Records作为匿名、不可变的聚合结构,无需定义自定义类即可捆绑多个对象。推荐在函数返回多个值或临时分组相关数据时使用。
应避免:
为简单的多值返回创建专用类。
dart
class UserResult {
final String name;
final int age;
UserResult(this.name, this.age);
}
UserResult fetchUser() {
return UserResult('Alice', 42);
}推荐:
使用Records动态无缝捆绑类型。
dart
(String, int) fetchUser() {
return ('Alice', 42);
}
void main() {
var user = fetchUser();
print(user.$1); // Alice
}Patterns and Pattern Matching
Patterns and Pattern Matching
Use patterns to destructure complex data into local variables and match against
specific shapes or values. Use them in , , or variable
declarations to unpack data directly.
switchif-caseAvoid:
Manually checking types, nulls, and keys for data extraction.
dart
void processJson(Map<String, dynamic> json) {
if (json.containsKey('name') && json['name'] is String &&
json.containsKey('age') && json['age'] is int) {
String name = json['name'];
int age = json['age'];
print('$name is $age years old.');
}
}Prefer:
Combining type-checking, validation, and assignment into a single statement.
dart
void processJson(Map<String, dynamic> json) {
if (json case {'name': String name, 'age': int age}) {
print('$name is $age years old.');
}
}使用Patterns将复杂数据解构为局部变量,并匹配特定的结构或值。可在、或变量声明中使用,直接解包数据。
switchif-case应避免:
手动检查类型、空值和键以提取数据。
dart
void processJson(Map<String, dynamic> json) {
if (json.containsKey('name') && json['name'] is String &&
json.containsKey('age') && json['age'] is int) {
String name = json['name'];
int age = json['age'];
print('$name is $age years old.');
}
}推荐:
将类型检查、验证和赋值合并为单个语句。
dart
void processJson(Map<String, dynamic> json) {
if (json case {'name': String name, 'age': int age}) {
print('$name is $age years old.');
}
}Switch Expressions
Switch Expressions
Use switch expressions to return a value directly, eliminating bulky and
statements.
casebreakAvoid:
Using switch statements where every branch simply returns or assigns a value.
dart
String describeStatus(int code) {
switch (code) {
case 200:
return 'Success';
case 404:
return 'Not Found';
default:
return 'Unknown';
}
}Prefer:
Returning the evaluated expression directly using the syntax.
=>dart
String describeStatus(int code) => switch (code) {
200 => 'Success',
404 => 'Not Found',
_ => 'Unknown',
};使用Switch Expressions直接返回值,消除冗余的和语句。
casebreak应避免:
在每个分支仅返回或赋值的场景使用switch语句。
dart
String describeStatus(int code) {
switch (code) {
case 200:
return 'Success';
case 404:
return 'Not Found';
default:
return 'Unknown';
}
}推荐:
使用语法直接返回求值表达式。
=>dart
String describeStatus(int code) => switch (code) {
200 => 'Success',
404 => 'Not Found',
_ => 'Unknown',
};Class Modifiers
Class Modifiers
Use class modifiers (, , , ) to restrict how
classes can be used outside their defines library. Prefer for defining
closed families of subtypes to enable exhaustive checking.
sealedfinalbaseinterfacesealedAvoid:
Using open classes when the set of subclasses is known and fixed.
abstractdart
abstract class Result {}
class Success extends Result {}
class Failure extends Result {}
String handle(Result r) {
if (r is Success) return 'OK';
if (r is Failure) return 'Error';
return 'Unknown';
}Prefer:
Using to guarantee to the compiler that all cases are covered.
sealeddart
sealed class Result {}
class Success extends Result {}
class Failure extends Result {}
String handle(Result r) => switch(r) {
Success() => 'OK',
Failure() => 'Error',
};使用类修饰符(、、、)限制类在其定义库之外的使用方式。推荐使用定义封闭的子类型家族,以支持穷尽检查。
sealedfinalbaseinterfacesealed应避免:
在子类集合已知且固定的场景使用开放的类。
abstractdart
abstract class Result {}
class Success extends Result {}
class Failure extends Result {}
String handle(Result r) {
if (r is Success) return 'OK';
if (r is Failure) return 'Error';
return 'Unknown';
}推荐:
使用向编译器保证所有情况都已覆盖。
sealeddart
sealed class Result {}
class Success extends Result {}
class Failure extends Result {}
String handle(Result r) => switch(r) {
Success() => 'OK',
Failure() => 'Error',
};Extension Types
Extension Types
Use extension types for a zero-cost wrapper around an existing type. Use them to
restrict operations or add custom behavior without runtime overhead.
Avoid:
Allocating new wrapper objects just for domain-specific logic or type safety.
dart
class Id {
final int value;
Id(this.value);
bool get isValid => value > 0;
}Prefer:
Using extension types which compile down to the underlying type at runtime.
dart
extension type Id(int value) {
bool get isValid => value > 0;
}使用Extension Types作为现有类型的零成本包装器。可用于限制操作或添加自定义行为,且无运行时开销。
应避免:
仅为领域特定逻辑或类型安全分配新的包装对象。
dart
class Id {
final int value;
Id(this.value);
bool get isValid => value > 0;
}推荐:
使用Extension Types,其在运行时会编译为底层类型。
dart
extension type Id(int value) {
bool get isValid => value > 0;
}Digit Separators
Digit Separators
Use underscores () in number literals strictly to improve visual readability
of large numeric values.
_Avoid:
Long number literals that are difficult to read at a glance.
dart
const int oneMillion = 1000000;Prefer:
Using underscores to separate thousands or other groupings.
dart
const int oneMillion = 1_000_000;在数字字面量中使用下划线()以提升大数值的视觉可读性。
_应避免:
使用难以一眼读取的长数字字面量。
dart
const int oneMillion = 1000000;推荐:
使用下划线分隔千位或其他分组。
dart
const int oneMillion = 1_000_000;Wildcard Variables
Wildcard Variables
Use wildcards () as non-binding variables or parameters to explicitly signal
that a value is intentionally unused.
_Avoid:
Inventing clunky, distinct variable names to avoid "unused variable" warnings.
dart
void handleEvent(String ignoredName, int status) {
print('Status: $status');
}Prefer:
Explicitly dropping the binding with an underscore.
dart
void handleEvent(String _, int status) {
print('Status: $status');
}使用通配符()作为非绑定变量或参数,明确表示该值是有意未使用的。
_应避免:
为避免"未使用变量"警告而创建笨拙的独特变量名。
dart
void handleEvent(String ignoredName, int status) {
print('Status: $status');
}推荐:
使用下划线明确放弃绑定。
dart
void handleEvent(String _, int status) {
print('Status: $status');
}Null-Aware Elements
Null-Aware Elements
Use null-aware elements () inside collection literals to conditionally
include items only if they evaluate to a non-null value.
?Avoid:
Using collection statements for simple null checks.
ifdart
var names = [
'Alice',
if (optionalName != null) optionalName,
'Charlie'
];Prefer:
Using the prefix inline.
?dart
var names = ['Alice', ?optionalName, 'Charlie'];在集合字面量中使用空感知元素(),仅当项的求值结果为非空时才条件性包含该元素。
?应避免:
对简单的空检查使用集合语句。
ifdart
var names = [
'Alice',
if (optionalName != null) optionalName,
'Charlie'
];推荐:
使用前缀内联处理。
?dart
var names = ['Alice', ?optionalName, 'Charlie'];Dot Shorthands
Dot Shorthands
Use dot shorthands to omit the explicit type name when it can be confidently
inferred from context, such as with enums or static fields.
Avoid:
Fully qualifying type names when the type is obvious from the context.
dart
LogLevel currentLevel = LogLevel.info;Prefer:
Reducing visual noise with inferred shorthand.
dart
LogLevel currentLevel = .info;使用Dot Shorthands省略显式类型名称,当类型可从上下文可靠推断时(如枚举或静态字段)。
应避免:
在类型从上下文可明显推断时仍完全限定类型名称。
dart
LogLevel currentLevel = LogLevel.info;推荐:
使用推断简写减少视觉干扰。
dart
LogLevel currentLevel = .info;Related Skills
相关技能
- : General code style and foundational Dart idioms that predate or complement the modern syntax features.
dart-best-practices
- : 通用代码风格和基础Dart惯用写法,早于或补充现代语法特性。
dart-best-practices