关于 dart-modern-features
面向 Dart 3.0 及以上版本开发者的现代语言特性指南,介绍记录、扩展类型、类修饰符等用法。也提供适用边界,避免与旧 SDK 约束或复杂公共 API 不匹配的改动。
主要功能
- 01使用记录返回多个值
- 02用类修饰符限制子类型
- 03用扩展类型构建零成本包装
- 04采用数字分隔符与通配符
- 05使用空感知集合元素和点简写
适用场景
- 01将多个返回值组合为记录
- 02为类定义明确的继承边界
- 03为领域类型添加类型安全包装
- 04现代化符合 Dart 3 条件的代码
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ kevmoo/ dash_skills --skill dart-modern-features安装后在 Claude Code 中输入/dart-modern-features确认已加载。
附带文件evals/evals.json
详细介绍
Dart 现代特性
1. 何时使用此技能
在以下情况下使用此技能:
- 编写或审查面向 Dart 3.0 或更高版本的 Dart 代码。
- 重构旧版 Dart 代码,以使用现代、简洁且零成本的特性,例如记录、扩展类型、类修饰符、空值感知集合元素、点简写和数字分隔符。
- 寻找以惯用方式处理多个返回值或零成本领域封装的方法。
对于模式匹配、switch 表达式以及列表/映射/拆分解构,请使用 dart-use-pattern-matching。对于将封闭类层次结构转换为穷尽式 sealed 类型,请使用 dart-seal-type-hierarchies。
何时不应使用(弃用防护规则)
在以下情况下,不要应用现代特性或重构代码:
- SDK 约束 < 3.0.0:包的
pubspec.yaml指定了支持 Dart 2.x 的 SDK 约束(例如,sdk: '>=2.19.0 <4.0.0')。重构为 Dart 3 特性会导致 Dart 2 用户遇到语法错误。 - 包含 > 3 个字段的公共 API 记录:记录适合承载 2~3 个返回值或内部元组,但对于复杂的公共 API 负载,专用类或扩展类型更清晰,也更易于扩展。
发现
查找可现代化的候选项:
空值感知元素
搜索用于检查空值的集合 if 语句:
- 正则表达式:
if\s*\(\w+\s*!=\s*null\)\s*\w+
数字分隔符
搜索未使用分隔符的长数字:
- 正则表达式:
\b\d{6,}\b(匹配 6 位或更多位数的数字)。
2. 特性
记录
使用记录作为匿名、不可变的聚合结构,将多个对象打包在一起,而无需定义自定义类。优先用于从函数返回多个值,或临时组合相关数据。
避免: 为简单的多值返回创建专用类。
class UserResult {
final String name;
final int age;
UserResult(this.name, this.age);
}
UserResult fetchUser() {
return UserResult('Alice', 42);
}
推荐: 使用记录即时无缝打包多种类型。
(String, int) fetchUser() {
return ('Alice', 42);
}
void main() {
var user = fetchUser();
print(user.$1); // Alice
}
类修饰符
使用类修饰符(final、base、interface、sealed)限制类在其定义库之外如何被继承:
interface class:外部库可以implement,但不能extend。base class:外部库可以extend,但不能implement(从而保留私有实现的不变量)。final class:外部库既不能extend,也不能implement。sealed class:在同一库中形成封闭的子类型族,支持穷尽式切换(参见 dart-seal-type-hierarchies)。
避免: 当必须强制执行不变量时,仍让内部实现类可被外部任意继承或实现其接口。
class TokenStore {
void save(String token) {}
}
推荐: 使用类修饰符明确声明子类型能力。
final class TokenStore {
void save(String token) {}
}
扩展类型
使用扩展类型为现有类型创建零成本封装。使用它们来限制操作或添加自定义行为,而不产生运行时开销。
避免: 仅为领域专属逻辑或类型安全而分配新的封装对象。
class Id {
final int value;
Id(this.value);
bool get isValid => value > 0;
}
推荐: 使用扩展类型,它们在运行时会编译为底层类型。
extension type Id(int value) {
bool get isValid => value > 0;
}
数字分隔符
严格使用数字字面量中的下划线(_)来提升大数值的视觉可读性。
避免: 使用一眼难以读清的长数字字面量。
const int oneMillion = 1000000;
推荐: 使用下划线分隔千位或其他数值分组。
const int oneMillion = 1_000_000;
通配符变量
使用通配符(_)作为非绑定变量或参数,明确表示有意忽略某个值。
避免: 为了避免“未使用变量”警告而起冗长又刻意不同的变量名。
void handleEvent(String ignoredName, int status) {
print('Status: $status');
}
推荐: 使用下划线明确丢弃绑定。
void handleEvent(String _, int status) {
print('Status: $status');
}
空值感知元素
在集合字面量中使用空值感知元素(?),仅在求值结果非空时才包含相应项。
避免: 对简单的空值检查使用集合 if 语句。
var names = [
'Alice',
if (optionalName != null) optionalName,
'Charlie'
];
推荐: 在行内使用 ? 前缀。
var names = ['Alice', ?optionalName, 'Charlie'];
点简写
当上下文能够明确推断出类型时(例如枚举或静态字段),使用点简写省略显式类型名称。
避免: 在类型可从上下文明确推断时,仍完整限定类型名称。
LogLevel currentLevel = LogLevel.info;
推荐: 使用推断出的简写,减少视觉干扰。
LogLevel currentLevel = .info;
相关技能
- dart-use-pattern-matching:Dart 3 模式匹配、switch 表达式以及列表/映射/
String.split()解构的权威指南。 - dart-seal-type-hierarchies:将封闭的类层次结构转换为
sealed类型,以支持穷尽式 switch。 - dart-best-practices:介绍早于现代语法功能或与其互补的通用代码风格和基础 Dart 惯用写法。