高效编写Dart--样式指南
如何阅读指南
-
DO
应始终遵循的准则 -
DON'T
不应该这么使用的准则 -
PREFER
应该遵循的准则,但是在某些情况下,可以根据个人理解忽略,不遵循 -
DON'T
不应该这么使用的准则 -
AVOID
不应该遵循的准则,但是在某些情况下,可以根据个人理解忽略,不遵循 -
CONSIDER
可遵循或者不遵循的规则,取决于个人偏好
标识符
主要有三种风格:
-
UpperCamelCase
每个单词的首字母大写 -
lowerCamelCase
首字母小写,其余每个单词的首字母大写 -
lowercase_with_underscores
单词全部使用小写,使用用_
分隔
DO 命名类型使用 UpperCamelCase 风格
Classes
(类), enums
(枚举), typedef
, and type parameters
(类型参数)应该大写每个单词的第一个字母(包括第一个单词),并且不使用分隔符。
Linter规则:camel_case_type
class SliderMenu { ... }
class HttpRequest { ... }
typedef Predicate<T> = bool Function(T value);
这甚至包括打算在元数据注释中使用的类。(关于元数据:使用元数据来给你的代码提供附加信息,以 @
字符开头,后面跟一个编译时的常量引用(例如 deprecated)或者调用常量构造器的语句。)
class Foo {
const Foo([arg]);
}
@Foo(anArg)
class A { ... }
@Foo()
class B { ... }
如果注释类的构造函数不带参数,则可能使用 lowerCamelCase 风格。
const foo = Foo();
@foo
class C { ... }
DO 命名libraries(库), packages(包), directories(目录), source files(源文件)使用 lowercase_with_underscores 风格
Linter规则:library_names, file_names
library peg_parser.source_scanner;
import 'file_system.dart';
import 'slider_menu.dart';
DO 命名导入文件的名称前缀使用 lowercase_with_underscores 风格
Linter规则:library_prefixes
import 'dart:math' as math;
import 'package:angular_components/angular_components'
as angular_components;
import 'package:js/js.dart' as js;
DO 命名其他标识符使用 lowerCamelCase 风格
Linter规则:non_constant_identifier_names
类成员
, 顶级定义
, 变量
, 参数
和命名参数
应该大写除第一个单词之外的每个单词的第一个字母,并且不使用分隔符。
var item;
HttpRequest httpRequest;
void align(bool clearItems) {
// ...
}
PREFER 命名常量使用 lowerCamelCase 风格
Linter规则:constant_identifier_names
const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');
class Dice {
static final numberGenerator = Random();
}
// 您可以使用`SCREAMING_CAPS`来保持与现有代码的一致性,如下所示:
// 1. 向已经使用 `SCREAMING_CAPS` 的文件或库添加代码时。
// 2. 当生成与Java代码并行的Dart代码时。如,在由protobufs生成的枚举类型中。
const PI = 3.14;
const DefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');
class Dice {
static final NUMBER_GENERATOR = Random();
}
DO 首字母缩写词和缩写词的首字母大写,长度不要超过两个字母。
大写的首字母缩写词很难读懂,多个相邻的首字母缩写词会导致名称含糊不清。例如,给定一个以HTTPSFTP 开头的名称,无法判断它是引用HTTPSFTP还是HTTPSFTP。
为了避免这种情况,缩略语和缩写词都像普通单词一样大写,只有两个字母
的缩略语除外。(ID和Mr这样的两个字母缩写仍然像单词一样大写。)
// Good
HttpConnectionInfo
uiHandler
IOStream
HttpRequest
Id
DB
// Bad
HTTPConnection
UiHandler
IoStream
HTTPRequest
ID
Db
DON’T 使用前缀字母
// Good
defaultTimeout
// Bad
kDefaultTimeout
排序
所有排序准则:directives_ordering
DO “dart:”引入放在最开始的地方
import 'dart:async';
import 'dart:html';
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
DO 在相对路径的引入之前 放置“package:”
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'util.dart';
PREFER 在导入自己的包之前 放置“package:”
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'package:my_package/util.dart';
DO 导出放在所有的导入之后
// Good
import 'src/error.dart';
import 'src/foo_bar.dart';
export 'src/error.dart';
// Bad
import 'src/error.dart';
export 'src/error.dart';
import 'src/foo_bar.dart';
DO 按字母顺序排序
// Good
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'foo.dart';
import 'foo/foo.dart';
// Bad
import 'package:foo/foo.dart';
import 'package:bar/bar.dart';
import 'foo/foo.dart';
import 'foo.dart';
格式化
DO 使用格式化代码 dartfmt
格式化是一项繁琐的工作,在重构过程中特别耗时。幸运的是,你不必担心它。我们提供了一个名为 dartfmt的自动代码格式化程序,它可 以为您完成代码格式化。我们有一些关于它适用的规则的文档,但是Dart的官方空白处理规则是dartfmt产生的。
其余的格式指南适用于dartfmt无法为您修复的一些内容。
CONSIDER 更改代码以使其更易于格式化
格式化程序可以使用你抛出的任何代码尽力而为,但它无法创造奇迹。如果您的代码具有特别长的标识符,深层嵌套的表达式,不同类型的运算符的混合等,格式化的输出可能仍然难以阅读。
发生这种情况时,请重新组织或简化代码。考虑缩短局部变量名称或将表达式提升到新的局部变量中。换句话说,如果您手动格式化代码并尝试使其更具可读性,请进行相同类型的修改。将dartfmt视为一种合作伙伴关系,您可以协同工作,有时可以迭代地生成漂亮的代码。
AVOID 避免行超过80个字符
尽量不要连续使用超过80个字符
DO 对所有流控制结构使用花括号
Linter规则:curly_braces_in_flow_control_structures
// Good
if (isWeekDay) {
print('Bike to work!');
} else {
print('Go dancing or read a book!');
}
if (arg == null) return defaultValue;
if (overflowChars != other.overflowChars) {
return overflowChars < other.overflowChars;
}
// Bad
if (overflowChars != other.overflowChars)
return overflowChars < other.overflowChars;