关于 effective-dart
effective-dart 是面向 Dart 和 Flutter 开发者的编码规范技能,整理 Effective Dart 风格、类型、结构、文档和测试建议,也包含代码审查检查项。
主要功能
- 01标识符命名规范
- 02类型与函数建议
- 03格式与文件组织指南
- 04文档和测试建议
- 05代码审查检查项
适用场景
- 01统一 Dart 项目的编码风格
- 02检查 Flutter 代码规范
- 03审查类型注解与 API 文档
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ evanca/ flutter-ai-rules --skill effective-dart安装后在 Claude Code 中输入/effective-dart确认已加载。
详细介绍
Effective Dart 技能
此技能介绍如何遵循 Effective Dart 指南,编写地道、高质量的 Dart 和 Flutter 代码。
1. 命名约定
| 类别 | 约定 | 示例 |
|---|---|---|
| 类、枚举、typedef、类型参数、扩展 | UpperCamelCase | MyWidget、UserState |
| 包、目录、源文件 | lowercase_with_underscores | user_profile.dart |
| 导入前缀 | lowercase_with_underscores | import '...' as my_prefix; |
| 变量、参数、命名参数、函数 | lowerCamelCase | userName、fetchData() |
- 将超过两个字母的首字母缩写和缩略词按单词形式书写:用
HttpRequest,不要用HTTPRequest。 - 除非缩写比完整术语更常见,否则避免使用缩写。
- 命名时,优先将最能描述用途的名词放在最后。
- 在代码中始终使用一致的术语。
- 遵循类型参数的助记命名约定:
E(元素)、K/V(键/值)、T/S/U(泛型类型)。 - 设计 API 时,可以考虑让代码读起来像一个句子。
- 非布尔属性或变量优先使用名词短语。
- 布尔属性或变量优先使用非祈使动词短语;优先使用肯定形式。
- 命名布尔参数时,可以考虑省略动词。
- 避免以
get开头命名函数或方法;如果 API 概念上用于访问属性,优先去掉get并使用 getter。
2. 类型和函数
- 使用类修饰符(
final、sealed、interface、base、mixin)控制类是否可以被扩展或实现。 - 对没有初始化器的变量标注类型。
- 如果字段和顶层变量的类型不明显,则标注类型。
- 在函数声明上标注返回类型。
- 在函数声明上标注参数类型。
- 对无法推断类型参数的泛型调用,写明类型参数。
- 推断失败时,使用
dynamic标注,而不是依赖推断。 - 不返回值的异步成员应使用
Future<void>作为返回类型。 - 对概念上用于访问属性的操作,使用 getter。
- 对概念上用于更改属性的操作,使用 setter。
- 使用函数声明将函数绑定到名称。
- 接收范围参数时,使用起始位置包含、结束位置不包含的约定。
// Prefer: explicit class modifier
final class AppConfig {
final String apiUrl;
final int timeout;
const AppConfig({required this.apiUrl, required this.timeout});
}
// Prefer: sealed for exhaustive pattern matching
sealed class Result<T> {}
class Success<T> extends Result<T> { final T value; Success(this.value); }
class Failure<T> extends Result<T> { final Exception error; Failure(this.error); }
3. 风格
dart format .
- 使用
dart format格式化代码;不要手动格式化。 - 所有流程控制语句都使用花括号。
- 变量值不会改变时,优先使用
final,而不是var。 - 编译时常量使用
const。 - 为提高可读性,行长优先控制在 80 个字符以内。
4. 导入和文件
- 不要导入其他包
src目录中的库。 - 不要让导入路径进入或离开
lib。 - 在包内优先使用相对导入路径。
- 导入路径中不要使用
/lib/或../。 - 可以考虑为库文件编写库级文档注释。
5. 结构
- 让文件专注于单一职责。
- 限制文件长度,以保持可读性。
- 将相关功能放在一起。
- 字段和顶层变量优先声明为
final。 - 如果类支持,可以考虑将构造函数声明为
const。 - 优先将声明设为私有——只公开必要内容。
6. 使用模式
// Adjacent string concatenation (not +)
final greeting = 'Hello, '
'world!';
// Collection literals
final list = [1, 2, 3];
final map = {'key': 'value'};
// Initializing formals
class Point {
final double x, y;
Point(this.x, this.y);
}
// Empty constructor body
class Empty {
Empty(); // not Empty() {}
}
// rethrow to preserve stack trace
try {
doSomething();
} catch (e) {
log(e);
rethrow;
}
- 使用
whereType<T>()按类型筛选集合。 - 为局部变量的
var和final用法遵循一致的规则。 - 尽可能在字段的声明处初始化字段。
- 如果重写了
==,也要重写hashCode;确保==遵循数学上的相等规则。 - 优先进行特定异常处理:使用
on SomeException catch (e),而不是宽泛的catch (e)或.catchError处理器。
7. 文档
/// Returns the sum of [a] and [b].
///
/// Throws [ArgumentError] if either value is negative.
int add(int a, int b) { ... }
- 将注释写成完整句子(首字母大写,以句号结尾)。
- 对类型和成员使用
///文档注释,而非/* */块注释。 - 优先为公共 API编写文档注释;也可以考虑为私有 API 编写。
- 文档注释应以单句摘要开头,并将摘要单独成段。
- 避免与周围上下文重复。
- 如果主要目的是产生副作用,函数/方法注释应以第三人称动词开头。
- 如果主要目的是返回值,则应以名词或非祈使动词短语开头。
- 布尔型变量/属性的注释应以“Whether”开头,后接名词或动名词短语。
- 在文档注释中使用
[identifier]引用作用域内的标识符。 - 使用散文说明参数、返回值和异常(例如,“The [param]”、“Returns”和“Throws”部分)。
- 将文档注释放在元数据注解之前。
- 说明代码存在的原因或应如何使用,而不只是说明它的功能。
8. 测试模式
- 使用
group和描述性test名称为业务逻辑编写单元测试:
import 'package:test/test.dart';
void main() {
group('CartService', () {
late CartService cart;
setUp(() => cart = CartService());
test('addItem increases item count', () {
cart.addItem(Product(id: '1', name: 'Widget', price: 9.99));
expect(cart.items, hasLength(1));
});
test('removeItem decreases total price', () {
final product = Product(id: '1', name: 'Widget', price: 9.99);
cart.addItem(product);
cart.removeItem(product.id);
expect(cart.totalPrice, equals(0.0));
});
});
}
- 使用
testWidgets和WidgetTester编写组件测试:
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('LoginButton shows loading indicator when tapped',
(WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: LoginScreen()));
await tester.tap(find.byType(ElevatedButton));
await tester.pump();
expect(find.byType(CircularProgressIndicator), findsOneWidget);
});
}
9. 代码审查工作流
审查 Dart 代码是否符合 Effective Dart 规范时,Agent 应检查:
- 命名——验证所有标识符均遵循第 1 节中的约定。
- 类型注解——确认公共 API 参数、返回类型和未初始化变量都带有类型注解。
- 类修饰符——验证在适当情况下使用
final、sealed或interface。 - 文档——确认所有公共成员都带有
///文档注释,且注释包含单句摘要。 - 风格——运行
dart format --output=none --set-exit-if-changed .验证格式。 - 分析——运行
dart analyze并确认没有问题。
参考资料
评论
支持 Markdown