Flutter 编写规范

缘起

代码对研发团队的重要性不言而喻。代码规范作为一个研发团队的核心基因,怎样在团队中高效传承是一个挑战。多人开发的团队中,每个人都有自己的喜好。代码管理应该避免出现“破窗效应”。一个人把代码写烂了,后面的同学照着写都烂了。正所谓,无规矩不成方圆。基础代码的表达,不追求绝对的对与错,追求的是在风格上的尽可能统一。

代码风格

驼峰

  • 类、枚举、typedef和类型参数
   class SliderMenu { ... }
   class HttpRequest { ... }

   typedef Predicate = bool Function(T value);
  • 使用小写加下划线来命名库和源文件
   library peg_parser.source_scanner;

   import 'file_system.dart';
   import 'slider_menu.dart';

不推荐如下写法:

 library pegparser.SourceScanner;

 import 'file-system.dart';
 import 'SliderMenu.dart';
  • 使用小驼峰法作为常量命名
 const pi = 3.14;
 const defaultTimeout = 1000;
 final urlScheme = RegExp('^([a-z]+):');

 class Dice {
    static final numberGenerator = Random();
  }
  • 不使用前缀字母
    因为Dart可以告诉您声明的类型、范围、可变性和其他属性,所以没有理由将这些属性编码为标识符名称。
 defaultTimeout

不推荐如下写法:

 kDefaultTimeout
  • required 关键字标识的变量请排到前面
 ChangeNotifierProvider({
    Key? key,
    required Create create,
    bool? lazy,
    TransitionBuilder? builder,
    Widget? child,
  }) 
  • 去除冗余new关键字
BaseOptions options =  BaseOptions(
        connectTimeout: 10 * 1000,
        receiveTimeout: 10 * 1000,
        sendTimeout: 10 * 1000,
        contentType: contentType);

不推荐使用

BaseOptions options = new BaseOptions(
        connectTimeout: 10 * 1000,
        receiveTimeout: 10 * 1000,
        sendTimeout: 10 * 1000,
        contentType: contentType);
  • flutter布局中优先使用SizedBox而不是Container

  • flutter颜色定义使用8位16进制整数标识颜色值

  • flutter widget在构造函数中加入key参数

  • 高效null处理
    dart语法中有很多null处理的语法糖,能大幅提升判空的效率,提升代码的健壮性。这里包括?的判断,??的判空,以及null safety。需要同学更多使用这样的语法来提升效率,而不是继续使用if else的冗杂表达。

排序

import顺序按照先dart引用,再package引用,再相对引用方式分模块。每个“部分”应该用空行分隔。

  • 在其他引入之前引入所需的dart库
     import 'dart:async';
     import 'dart:html';

     import 'package:bar/bar.dart';
     import 'package:foo/foo.dart';
  • 第三方包的导入先于其他包
 import 'package:bar/bar.dart';
 import 'package:foo/foo.dart';
  
 import 'package:my_package/util.dart';
  • 在所有导入之后,在单独的部分中指定导出
  import 'src/error.dart';
  import 'src/foo_bar.dart';
  
  export 'src/error.dart';

不推荐如下写法:

  import 'src/error.dart';
  export 'src/error.dart';
  import 'src/foo_bar.dart';

格式化

  • 所有流控制结构,请使用大括号

这样做可以避免悬浮的else问题

  if (isWeekDay) {
    print('Bike to work!');
  } else {
    print('Go dancing or read a book!');
  }
  • 例外

一个if语句没有else子句,其中整个if语句和then主体都适合一行。在这种情况下,如果你喜欢的话,你可以去掉大括号

  if (arg == null) return defaultValue;

如果流程体超出了一行需要分划请使用大括号:

  if (overflowChars != other.overflowChars) {
    return overflowChars < other.overflowChars;
  }

不推荐如下写法:

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

注释

  • 要像句子一样格式化

除非是区分大小写的标识符,否则第一个单词要大写。以句号结尾(或“!”或“?”)。对于所有的注释都是如此:doc注释、内联内容,甚至TODOs。即使是一个句子片段。

  greet(name) {
    // Assume we have a valid name.
    print('Hi, $name!');
  }

不推荐如下写法:

  greet(name) {
    /* Assume we have a valid name. */
    print('Hi, $name!');
  }

可以使用块注释(/…/)临时注释掉一段代码,但是所有其他注释都应该使用//

减少歧义

  • 显式变量类型
    好处是直观,减少不必要的推断。最终经过激烈讨论,大家还是决定采用明确变量类型的方案。从实践角度出发,直接明确变量类型虽然从表达上略冗杂,但是歧义确实更少。
  final bool autofocus;
  final String obscuringCharacter;
  final bool obscureText;
  final bool autocorrect;
  • 变量/函数状态坚持最小化表达

一个变量或者方法如果重写了,请明确加上override注解。一个变量如果确定是const变量,请加上const关键字。一个变量如果没有再被赋值,请定义成final。坚持最小化表达,有如下几点收益:

  1. 最小化变量状态表达能精准刻画变量状态

2.最小化变量状态是指用最严格的属性描述变量。例如一个变量从之前的多处赋值,改为一处赋值。那么变量其实自带了final的隐形属性。最小化状态表达要求必须加上final关键字,而不是推断是final。因为一旦加上final关键字,后续在赋值就会报错。这能减少不必要的理解成本,最大限度避免变量状态的隐形改变。
提升代码性能
3.增加的final const关键字能让编译器做更多优化,提升代码的整体性能。

代码质量

  • 避免给void赋值 【void_checks】
  • 变量比较之前先判断类型 【unrelated_type_equality_checks】
  • 避免catch 空实现【empty_catches】
  • 避免使用隐形类型传递 【avoid_shadowing_type_parameters】
  • 避免await 非future对象 【await_only_futures】
  • 集合的remove需要传递符合集合的类型的参数【list_remove_unrelated_type】

你可能感兴趣的:(Flutter 编写规范)