# Dart代码编写规则

# 文件名命名规范

文件及文件夹名称采用下划线命名法,例:

my_widget/
├── empty_list.dart
├── form_widgets.dart
├── handwritten_signature.dart
├── installed_car_card.dart
├── launch_card.dart
├── loading_more.dart
├── loading_spinner.dart
├── my_button.dart
├── my_dialog.dart
├── my_picker.dart
├── recent_car_card.dart
├── search_bar.dart
├── show_document.dart
├── upgrade_dialog.dart
└── upload_images.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 代码编写规则-引入pedantic

友情提示

此规则不包含格式化规则,请手动格式化代码

  1. pubspec.yaml中引入pedantic,放在dev_dependencies下面
dev_dependencies:
  pedantic: ^1.9.0
1
2
  1. 在项目根目录新建文件analysis_options.yaml,内容:
# 导入pedantic规则
include: package:pedantic/analysis_options.yaml
1
2
  1. 保存,完成

# 代码编写规则-详细规则说明

提示

以下中文大部分为机器翻译,仅供参考
最好直接看代码,比较清晰

  1. always_declare_return_types

    官方解释及翻译

    declare method return types.
    声明方法的返回类型

    错误示例❌

     

     


     


    main() { }
    
    _bar() => _Foo();
    
    class _Foo {
      _foo() => 42;
    }
    
    1
    2
    3
    4
    5
    6
    7

    正确示例✅

     

     


     


    void main() { }
    
    _Foo _bar() => _Foo();
    
    class _Foo {
      int _foo() => 42;
    }
    
    1
    2
    3
    4
    5
    6
    7
  2. always_require_non_null_named_parameters

    官方解释及翻译

    specify @required on named parameters without a default value on which an assert(param != null) is done.
    如果参数加了非空断言,则此参数是必传的@required或者此参数有一个非空默认值

    错误示例❌

    void m1({a}) {
      assert(a != null);
    }
    
    1
    2
    3

    正确示例✅

    void m1({ a}) {
      assert(a != null);
    }
    
    void m2({a: 1}) {
      assert(a != null);
    }
    
    1
    2
    3
    4
    5
    6
    7
  3. annotate_overrides

    官方解释及翻译

    annotate overridden methods and fields.
    重写方法必须加@override注解

    错误示例❌

    class Cat {
      int get lives => 9;
    }
    
    class Lucky extends Cat {
      final int lives = 14;
    }
    
    1
    2
    3
    4
    5
    6
    7

    正确示例✅








     


     



    abstract class Dog {
      String get breed;
      void bark() {}
    }
    
    class Husky extends Dog {
    
      
      final String breed = 'Husky';
    
      
      void bark() {}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  4. avoid_empty_else

    官方解释及翻译

    AVOID empty else statements.
    避免空的else语句

    错误示例❌

    if (x > y)
      print("1");
    else ;
    print("2");
    
    1
    2
    3
    4

    正确示例✅






    if (x > y)
      print("1");
    else
      print("2");
    
    1
    2
    3
    4
  5. avoid_init_to_null

    官方解释及翻译

    Don't explicitly initialize variables to null.
    不要将变量显式初始化为null

    错误示例❌

     


     









    int _nextId = null;
    
    class LazyId {
      int _id = null;
    
      int get id {
        if (_nextId == null) _nextId = 0;
        if (_id == null) _id = _nextId++;
    
        return _id;
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    正确示例✅

     


     









    int _nextId;
    
    class LazyId {
      int _id;
    
      int get id {
        if (_nextId == null) _nextId = 0;
        if (_id == null) _id = _nextId++;
    
        return _id;
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
  6. avoid_null_checks_in_equality_operators

    官方解释及翻译

    DON'T check for null in custom == operators.
    不要在自定义==运算符中检查null

    错误示例❌

    class Person {
      final String name;
    
      
      operator == (other) =>
          other != null && other is Person && name == other.name;
    }
    
    1
    2
    3
    4
    5
    6
    7

    正确示例✅

    class Person {
      final String name;
    
      
      operator == (other) => other is Person && name == other.name;
    }
    
    1
    2
    3
    4
    5
    6
  7. avoid_relative_lib_imports

    官方解释及翻译

    DO avoid relative imports for files in lib/.
    避免使用相对路径导入文件

    错误示例❌

    import 'package:foo/bar.dart';
    
    import '../lib/baz.dart';
    
    1
    2
    3

    正确示例✅

    import 'package:foo/bar.dart';
    
    import 'baz.dart';
    
    1
    2
    3
  8. avoid_return_types_on_setters

    官方解释及翻译

    AVOID return types on setters.
    避免在set方法上声明返回类型

    错误示例❌

    void set speed(int ms);
    
    1

    正确示例✅

    set speed(int ms);
    
    1
  9. avoid_shadowing_type_parameters

    官方解释及翻译

    AVOID shadowing type parameters.
    避免隐蔽类型参数

    错误示例❌

    class A<T> {
      void fn<T>() {}
    }
    
    1
    2
    3

    正确示例✅

    class A<T> {
      void fn<U>() {}
    }
    
    1
    2
    3
  10. avoid_types_as_parameter_names

    官方解释及翻译

    AVOID using a parameter name that is the same as an existing type.
    避免使用与现有类型相同的参数名

    错误示例❌

    m(f(int));
    
    1

    正确示例✅

    m(f(int v));
    
    1
  11. camel_case_extensions

    官方解释及翻译

    DO name extensions using UpperCamelCase.
    extensions命名规范采用帕斯卡命名法

    正确示例✅

    extension MyFancyList<T> on List<T> { 
      // ... 
    }
    
    extension SmartIterable<T> on Iterable<T> {
      // ...
    }
    
    1
    2
    3
    4
    5
    6
    7
  12. curly_braces_in_flow_control_structures

    官方解释及翻译

    DO use curly braces for all flow control structures.
    所有逻辑控制语句都要使用花括号

    错误示例❌

    if (overflowChars != other.overflowChars)
      return overflowChars < other.overflowChars;
    
    1
    2

    正确示例✅

    if (overflowChars != other.overflowChars) {
      return overflowChars < other.overflowChars;
    }
    
    1
    2
    3
  13. empty_catches

    官方解释及翻译

    AVOID empty catch blocks.
    避免空的catch块

    错误示例❌

    try {
      dio.get();
    } catch(exception) { }
    
    1
    2
    3

    正确示例✅

    try {
      dio.get();
    } catch(e) {
      doSomething(e);
    }
    
    1
    2
    3
    4
    5
  14. empty_constructor_bodies

    官方解释及翻译

    DO use ; instead of {} for empty constructor bodies.
    使用分号代替空构造方法块的花括号

    错误示例❌

    class Point {
      int x, y;
      Point(this.x, this.y) {}
    }
    
    1
    2
    3
    4

    正确示例✅

    class Point {
      int x, y;
      Point(this.x, this.y);
    }
    
    1
    2
    3
    4
  15. library_names

    官方解释及翻译

    DO name libraries using lowercase_with_underscores.
    library命名规范采用下划线命名法

    错误示例❌

    library peg-parser;
    
    1

    正确示例✅

    library peg_parser;
    
    1
  16. library_prefixes

    官方解释及翻译

    DO use lowercase_with_underscores when specifying a library prefix.
    指定库前缀时,请使用下划线命名法

    错误示例❌

    import 'dart:math' as Math;
    import 'dart:json' as JSON;
    import 'package:js/js.dart' as JS;
    import 'package:javascript_utils/javascript_utils.dart' as jsUtils;
    
    1
    2
    3
    4

    正确示例✅

    import 'dart:math' as math;
    import 'dart:json' as json;
    import 'package:js/js.dart' as js;
    import 'package:javascript_utils/javascript_utils.dart' as js_utils;
    
    1
    2
    3
    4
  17. no_duplicate_case_values

    官方解释及翻译

    DON'T use more than one case with same value.
    switch case中请勿添加多个相同的值

    错误示例❌

    const int A = 1;
    switch (v) {
      case 1:
      case 2:
      case A:
      case 2:
    }
    
    1
    2
    3
    4
    5
    6
    7

    正确示例✅

    const int A = 1;
    switch (v) {
      case A:
      case 2:
    }
    
    1
    2
    3
    4
    5
  18. null_closures

    官方解释及翻译

    DO NOT pass null as an argument where a closure is expected.
    不要在期望关闭的地方传递null作为参数

    错误示例❌

    [1, 3, 5].firstWhere((e) => e.isOdd, orElse: null);
    
    1

    正确示例✅

    [1, 3, 5].firstWhere((e) => e.isOdd, orElse: () => null);
    
    1
  19. omit_local_variable_types

    官方解释及翻译

    CONSIDER omitting type annotations for local variables.
    考虑忽略局部变量的类型注释

    错误示例❌

    Map<int, List<Person>> groupByZip(Iterable<Person> people) {
      Map<int, List<Person>> peopleByZip = <int, List<Person>>{};
      for (Person person in people) {
        peopleByZip.putIfAbsent(person.zip, () => <Person>[]);
        peopleByZip[person.zip].add(person);
      }
      return peopleByZip;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

    正确示例✅

    Map<int, List<Person>> groupByZip(Iterable<Person> people) {
      var peopleByZip = <int, List<Person>>{};
      for (var person in people) {
        peopleByZip.putIfAbsent(person.zip, () => <Person>[]);
        peopleByZip[person.zip].add(person);
      }
      return peopleByZip;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
  20. prefer_adjacent_string_concatenation

    官方解释及翻译

    DO use adjacent strings to concatenate string literals.
    使用相邻的字符串来连接字符串文字

    错误示例❌

    raiseAlarm(
    'ERROR: Parts of the spaceship are on fire. Other ' +
    'parts are overrun by martians. Unclear which are which.');
    
    1
    2
    3

    正确示例✅

    raiseAlarm(
    'ERROR: Parts of the spaceship are on fire. Other '
    'parts are overrun by martians. Unclear which are which.');
    
    1
    2
    3
  21. prefer_collection_literals

    官方解释及翻译

    DO use collection literals when possible.
    尽可能使用集合文字

    错误示例❌

    var points = new List();
    var addresses = new Map();
    var uniqueNames = new Set();
    var ids = new LinkedHashSet();
    var coordinates = new LinkedHashMap();
    
    1
    2
    3
    4
    5

    正确示例✅

    var points = [];
    var addresses = <String,String>{};
    var uniqueNames = <String>{};
    var ids = <int>{};
    var coordinates = <int,int>{};
    
    1
    2
    3
    4
    5
  22. prefer_conditional_assignment

    官方解释及翻译

    PREFER using ??= over testing for null.
    使用??=判空并赋值

    错误示例❌

    String get fullName {
      if (_fullName == null) {
        _fullName = getFullUserName(this);
      }
      return _fullName;
    }
    
    1
    2
    3
    4
    5
    6

    正确示例✅

    String get fullName {
      return _fullName ??= getFullUserName(this);
    }
    
    1
    2
    3
  23. prefer_contains

    官方解释及翻译

    DON'T use indexOf to see if a collection contains an element.
    不要使用indexOf来判断集合是否包含某个元素

    错误示例❌

    if (lunchBox.indexOf('sandwich') == -1 return 'so hungry...';
    
    1

    正确示例✅

    if (!lunchBox.contains('sandwich') return 'so hungry...';
    
    1
  24. prefer_equal_for_default_values

    官方解释及翻译

    DO Use = to separate a named parameter from its default value.
    使用=给参数设置默认值

    错误示例❌

    m({a: 1})
    
    1

    正确示例✅

    m({a = 1})
    
    1
  25. prefer_final_fields

    官方解释及翻译

    DO prefer declaring private fields as final if they are not reassigned later in the class.
    如果不稍后在类中重新分配私有字段,请不要将私有字段声明为final

    错误示例❌

    class BadImmutable {
      var _label = 'hola mundo! BadImmutable'; // LINT
      var label = 'hola mundo! BadImmutable'; // OK
    }
    
    1
    2
    3
    4

    正确示例✅

    class GoodImmutable {
      final label = 'hola mundo! BadImmutable', bla = 5; // OK
      final _label = 'hola mundo! BadImmutable', _bla = 5; // OK
    }
    
    1
    2
    3
    4
  26. prefer_for_elements_to_map_fromIterable

    官方解释及翻译

    When building maps from iterables, it is preferable to use for elements.
    从可迭代对象构建map时,最好用于元素

    错误示例❌

    Map<String, WidgetBuilder>.fromIterable(
      kAllGalleryDemos,
      key: (demo) => '${demo.routeName}',
      value: (demo) => demo.buildRoute,
    );
    
    1
    2
    3
    4
    5

    正确示例✅

    return {
      for (var demo in kAllGalleryDemos) {
        '${demo.routeName}': demo.buildRoute,
      }
    };
    
    1
    2
    3
    4
    5
  27. prefer_generic_function_type_aliases

    官方解释及翻译

    PREFER generic function type aliases.
    优选通用函数类型别名

    错误示例❌

    typedef void F();
    
    1

    正确示例✅

    typedef F = void Function();
    
    1
  28. prefer_if_null_operators

    官方解释及翻译

    Prefer using if null operators instead of null checks in conditional expressions.
    最好在条件表达式中使用??运算符而不是空检查

    错误示例❌

    v = a == null ? b : a;
    
    1

    正确示例✅

    v = a ?? b;
    
    1
  29. prefer_is_empty

    官方解释及翻译

    DON'T use length to see if a collection is empty.
    不要使用length属性来查看集合是否为空

    错误示例❌

    if (lunchBox.length == 0) return 'so hungry...';
    if (words.length != 0) return words.join(' ');
    
    1
    2

    正确示例✅

    if (lunchBox.isEmpty) return 'so hungry...';
    if (words.isNotEmpty) return words.join(' ');
    
    1
    2
  30. prefer_is_not_empty

    官方解释及翻译

    PREFER x.isNotEmpty to !x.isEmpty for Iterable and Map instances.
    对于Iterable和Map实例,直接只用isNotEmpty判断其长度不是0

    错误示例❌

    if (!sources.isEmpty) {
      process(sources);
    }
    
    1
    2
    3

    正确示例✅

    if (todo.isNotEmpty) {
      sendResults(request, todo.isEmpty);
    }
    
    1
    2
    3
  31. prefer_iterable_whereType

    官方解释

    PREFER iterable.whereType<T>() over iterable.where((e) => e is T).

    错误示例❌

    iterable.where((e) => e is MyClass)
    
    1

    正确示例✅

    iterable.whereType<MyClass>()
    
    1
  32. prefer_single_quotes

    官方解释及翻译

    DO use single quotes where they wouldn't require additional escapes.
    除非字符串内部还有引号,否则字符串最外部的引号都使用单引号

    错误示例❌

    useStrings(
      "should be single quote",
      r"should be single quote",
      r"""should be single quotes""")
    
    1
    2
    3
    4

    正确示例✅

    useStrings(
      'should be single quote',
      r'should be single quote',
      r'''should be single quotes''',
      "here's ok",
      "nested ${a ? 'strings' : 'can'} be wrapped by a double quote",
      'and nested ${a ? "strings" : "can be double quoted themselves"}');
    
    1
    2
    3
    4
    5
    6
    7
  33. prefer_spread_collections

    官方解释及翻译

    Use spread collections when possible.
    尽可能使用spread方式合并集合

    错误示例❌

    Widget build(BuildContext context) {
      return CupertinoPageScaffold(
        child: ListView(
          children: [
            Tab2Header(),
          ]..addAll(buildTab2Conversation()),
        ),
      );
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    正确示例✅

    Widget build(BuildContext context) {
      return CupertinoPageScaffold(
        child: ListView(
          children: [
            Tab2Header(),
            ...buildTab2Conversation(),
          ],
        ),
      );
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  34. recursive_getters

    官方解释及翻译

    DON'T create recursive getters.
    不要创建递归的get方法

    错误示例❌

    int get field => field;
    
    1

    正确示例✅

    int get field => _field;
    
    1
  35. slash_for_doc_comments

    官方解释及翻译

    PREFER using /// for doc comments.
    使用///作为文档注释的首选项

    正确示例✅

    /// Parses a set of option strings. For each option:
    ///
    /// * If it is `null`, then it is ignored.
    /// * If it is a string, then [validate] is called on it.
    /// * If it is any other type, it is *not* validated.
    void parse(List options) {
      // ...
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
  36. type_init_formals

    官方解释及翻译

    DON'T type annotate initializing formals.
    不要键入注释形式化形式

    错误示例❌

    class Point {
      int x, y;
      Point(int this.x, int this.y);
    }
    
    1
    2
    3
    4

    正确示例✅

    class Point {
      int x, y;
      Point(this.x, this.y);
    }
    
    1
    2
    3
    4
  37. unawaited_futures

    官方解释

    DO await functions that return a Future inside of an async function body.

    错误示例❌

    void main() async {
      doSomething(); // Likely a bug.
    }
    
    1
    2
    3

    正确示例✅

    Future doSomething() => ...;
    
    void main() async {
      await doSomething();
    
      unawaited(doSomething()); // Explicitly-ignored fire-and-forget.
    }
    
    1
    2
    3
    4
    5
    6
    7
  38. unnecessary_const

    官方解释及翻译

    AVOID repeating const keyword in a const context.
    在const上下文中避免重复使用const关键字

    错误示例❌

    class A { const A(); }
    void m() {
      const a = const A();
      final b = const [const A()];
    }
    
    1
    2
    3
    4
    5

    正确示例✅

    class A { const A(); }
    void m() {
      const a = A();
      final b = const [A()];
    }
    
    1
    2
    3
    4
    5
  39. unnecessary_new

    官方解释及翻译

    AVOID new keyword to create instances.
    新建实例省略new关键字

    错误示例❌

    class A { A(); }
    void m() {
      final a = new A();
    }
    
    1
    2
    3
    4

    正确示例✅

    class A { A(); }
    void m() {
      final a = A();
    }
    
    1
    2
    3
    4
  40. unnecessary_null_in_if_null_operators

    官方解释及翻译

    AVOID using null as an operand in if null operators.
    如果为null运算符,则避免使用null作为操作数

    错误示例❌

    var x = a ?? null;
    var y = null ?? 1;
    
    1
    2

    正确示例✅

    var x = a ?? 1;
    
    1
  41. unnecessary_this

    官方解释及翻译

    DON'T use this when not needed to avoid shadowing.
    不需要时请省略this

    错误示例❌




     



    class Box {
      var value;
      void update(new_value) {
        this.value = new_value;
      }
    }
    
    1
    2
    3
    4
    5
    6

    正确示例✅




     



    class Box {
      var value;
      void update(new_value) {
        value = new_value;
      }
    }
    
    1
    2
    3
    4
    5
    6
  42. unrelated_type_equality_checks

    官方解释及翻译

    DON'T Compare references of unrelated types for equality.
    请勿比较无关类型的引用是否相等

    错误示例❌



     


    void someFunction() {
      var x = '1';
      if (x == 1) print('someFunction'); // LINT
    }
    
    1
    2
    3
    4

    正确示例✅



     


    void someFunction() {
      var x = '1';
      if (x == '1') print('someFunction'); // LINT
    }
    
    1
    2
    3
    4
  43. use_function_type_syntax_for_parameters

    官方解释及翻译

    Use generic function type syntax for parameters.
    对参数使用通用函数类型语法

    错误示例❌

    Iterable<T> where(bool predicate(T element)) {}
    
    1

    正确示例✅

    Iterable<T> where(bool Function(T) predicate) {}
    
    1
  44. use_rethrow_when_possible

    官方解释及翻译

    DO use rethrow to rethrow a caught exception.
    请使用rethrow重新抛出捕获的异常

    错误示例❌

    try {
      somethingRisky();
    } catch(e) {
      if (!canHandle(e)) throw e;
      handle(e);
    }
    
    1
    2
    3
    4
    5
    6

    正确示例✅

    try {
      somethingRisky();
    } catch(e) {
      if (!canHandle(e)) rethrow;
      handle(e);
    }
    
    1
    2
    3
    4
    5
    6
  45. valid_regexps

    官方解释及翻译

    DO use valid regular expression syntax when creating regular expression instances.
    创建正则表达式实例时,请使用有效的正则表达式语法

    错误示例❌

    print(RegExp('(').hasMatch('foo()'));
    
    1

    正确示例✅

    print(RegExp('[(]').hasMatch('foo()'));
    
    1
上次更新: 7/10/2020, 4:18:52 PM