重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
dart-modern-features by kevmoo/dash_skills
npx skills add https://github.com/kevmoo/dash_skills --skill dart-modern-features在以下情况下使用此技能:
使用记录作为匿名的、不可变的聚合结构,无需定义自定义类即可捆绑多个对象。对于从函数返回多个值或临时分组相关数据,优先使用它们。
避免: 为简单的多值返回创建专门的类。
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
}
使用模式将复杂数据解构为局部变量,并根据特定形状或值进行匹配。在 switch、if-case 或变量声明中使用它们来直接解包数据。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
避免: 手动检查类型、空值和键以提取数据。
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.');
}
}
推荐: 将类型检查、验证和赋值合并到单个语句中。
void processJson(Map<String, dynamic> json) {
if (json case {'name': String name, 'age': int age}) {
print('$name is $age years old.');
}
}
使用 switch 表达式直接返回值,消除冗长的 case 和 break 语句。
避免: 在每个分支仅简单返回值或赋值的情况下使用 switch 语句。
String describeStatus(int code) {
switch (code) {
case 200:
return 'Success';
case 404:
return 'Not Found';
default:
return 'Unknown';
}
}
推荐: 使用 => 语法直接返回求值后的表达式。
String describeStatus(int code) => switch (code) {
200 => 'Success',
404 => 'Not Found',
_ => 'Unknown',
};
使用类修饰符(sealed、final、base、interface)来限制类在其定义库之外的使用方式。对于定义封闭的子类型族以实现穷尽性检查,优先使用 sealed。
避免: 在子类集合已知且固定的情况下使用开放的 abstract 类。
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';
}
推荐: 使用 sealed 向编译器保证所有情况都已覆盖。
sealed class Result {}
class Success extends Result {}
class Failure extends Result {}
String handle(Result r) => switch(r) {
Success() => 'OK',
Failure() => 'Error',
};
使用扩展类型作为现有类型的零成本包装器。使用它们来限制操作或添加自定义行为,而无需运行时开销。
避免: 仅为特定领域的逻辑或类型安全而分配新的包装器对象。
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-best-practices : 早于或补充现代语法特性的通用代码风格和基础 Dart 惯用法。每周安装次数
67
代码仓库
GitHub 星标数
119
首次出现
2026年2月26日
安全审计
安装于
antigravity51
github-copilot26
codex26
opencode25
amp25
cline25
Use this skill when:
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.
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.
(String, int) fetchUser() {
return ('Alice', 42);
}
void main() {
var user = fetchUser();
print(user.$1); // Alice
}
Use patterns to destructure complex data into local variables and match against specific shapes or values. Use them in switch, if-case, or variable declarations to unpack data directly.
Avoid: Manually checking types, nulls, and keys for data extraction.
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.
void processJson(Map<String, dynamic> json) {
if (json case {'name': String name, 'age': int age}) {
print('$name is $age years old.');
}
}
Use switch expressions to return a value directly, eliminating bulky case and break statements.
Avoid: Using switch statements where every branch simply returns or assigns a value.
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.
String describeStatus(int code) => switch (code) {
200 => 'Success',
404 => 'Not Found',
_ => 'Unknown',
};
Use class modifiers (sealed, final, base, interface) to restrict how classes can be used outside their defines library. Prefer sealed for defining closed families of subtypes to enable exhaustive checking.
Avoid: Using open abstract classes when the set of subclasses is known and fixed.
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 sealed to guarantee to the compiler that all cases are covered.
sealed class Result {}
class Success extends Result {}
class Failure extends Result {}
String handle(Result r) => switch(r) {
Success() => 'OK',
Failure() => 'Error',
};
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.
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.
extension type Id(int value) {
bool get isValid => value > 0;
}
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.
const int oneMillion = 1000000;
Prefer: Using underscores to separate thousands or other groupings.
const int oneMillion = 1_000_000;
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.
void handleEvent(String ignoredName, int status) {
print('Status: $status');
}
Prefer: Explicitly dropping the binding with an underscore.
void handleEvent(String _, int status) {
print('Status: $status');
}
Use null-aware elements (?) inside collection literals to conditionally include items only if they evaluate to a non-null value.
Avoid: Using collection if statements for simple null checks.
var names = [
'Alice',
if (optionalName != null) optionalName,
'Charlie'
];
Prefer: Using the ? prefix inline.
var names = ['Alice', ?optionalName, 'Charlie'];
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.
LogLevel currentLevel = LogLevel.info;
Prefer: Reducing visual noise with inferred shorthand.
LogLevel currentLevel = .info;
dart-best-practices : General code style and foundational Dart idioms that predate or complement the modern syntax features.Weekly Installs
67
Repository
GitHub Stars
119
First Seen
Feb 26, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
antigravity51
github-copilot26
codex26
opencode25
amp25
cline25
Next.js 15+ 最佳实践指南:文件约定、RSC边界、异步模式与性能优化
1,200 周安装