Effective Dart - Dart语言的高效之路

前言
本系列只为了把官网的EffectiveDart篇章翻译成中文,以便209的那班学生可以更好的撸代码,你们英文真的太菜了。。。

原地址

https://dart.dev/guides/language/effective-dart

在过去的几年中,我们已经编写了大量的Dart代码,并了解了很多关于哪些是好的代码,哪些不是。我们将与您共享这些信息,以便您也可以编写一致、健壮、高效的代码。下面是两大非常重要的主题:

保持一致

当涉及到格式和大小写时,争论哪种方案更好是带有主观色彩的也不可能得到解决。我们所知道的是,保持一致在客观上是有帮助的。
如果两段代码看起来不同,那应该是因为它们在某种意义上是不同的。当一段代码凸显出来并吸引了别人的眼球时,应该是出于实用、有用的原因。

简洁

Dart在设计时继承了许多与C、Java、JavaScript和其他语言相同的语句和表达式,所以在设计之初就希望这门语言在开发者眼里是熟悉的。但Dart在这些语言的基础上还进行了很大的改进。我们添加了一系列功能,从字符串插值到初始化表单,以帮助开发者更简单、更容易地表达意图。
如果有多种表达的方式,我们通常应该选择最简单明了的那种。这并不是说你应该像打高尔夫球尽可能少的击球一样尽可能的把整个程序塞进一行代码里。目标是代码要写的简洁,而不是密集繁杂。

Dart分析器有一个linter可以帮助程序员编写良好的、一致的代码。如果存在能够帮助程序员遵循指南的LITER规则,那么指南就是细化了上述规则。下面是一个例子:
Linter rule: prefer_collection_literals
For help on enabling linter rules, see the documentation for customizing static analysis

1.指南

为了便于大家理解,我们把指南分成了下面几个部分:

1.1 样式指南

定义了代码的布局和组织规则,或者至少定义了在dartfmt工具中不能为开发者处理的部分。样式指南还指定了标识符的格式如驼峰命名、如何使用下划线等。

1.2 文档指南

讲述了开发者需要知道的关于注释的所有信息。文档注释和常规运行代码注释。

1.3 使用指南

在这里将讨论如何在语句或表达式中充分利用语言特性来实现业务功能。

1.4 设计指南

在这里讲讨论我们在为库设计一致的、可用的API时所学到的知识。所讨论的内容是非常代码层面的,但也是范围最宽泛的。同时也涵盖了类型定义和声明。

For links to all the guidelines, see the summary.

2.如何阅读指南

每个指南分成几个部分。每个部分都包含一个指南列表。每一条准则都以以下一个词开头:

2.1 DO(要做)应当遵守的规则
2.2 DON‘T (不要做)不应该做的
2.3 PREFER 应该遵循
2.4 AVIOD 尽量避免
2.5 CONSIDER 可遵守可不遵守,取决于自己的喜好

一些准则描述了规则不适用的例外情况。列出的例外情况可能并不详尽,您可能仍需要对其他情况作出判断。
上面的指南听起来像是如果你的鞋带没系好,警察会敲你家门一样。其实事情没有那么多糟糕。这里的指导其实大多是编写代码的常识。我们的目标,永远只有一个,那就是,编写简洁的、高可读性的和可维护的代码。

3. 词汇表

3.1 library member (库成员)

库成员是最高级别的字段、getter方法、setter方法或函数。基本上,任何最高级的都不是一种类型。

3.2 class member(类成员)

类成员是在类中声明的构造函数、字段、getter、setter、函数或运算符。类成员可以是实例或静态、抽象或具体的。

3.3 member(成员)

成员可以是库成员,也可以是类成员。

3.4 variable (变量)

通常使用的变量是最高级别的变量、参数和局部变量。它不包括静态或实例字段。

3.5 type(类型)

类型是任何一种类型声明:类、typedef或枚举。

3.6 property(属性)

属性是最高级别的变量、getter(在类内部或最高级别的、实例或静态)、setter(同级的)或field(实例或静态)。大致上任何“域”的命名构造。

4. 规则摘要

4.1 样式

4.1.1 标示符

DO          使用大写的驼峰命名type类型。
DO          使用大写的驼峰命名extension扩展。
DO          使用带下划线的小写字母命名库、包、目录和源文件。
DO          使用带下划线的小写字母输入前缀。
DO          使用小写字母命名其他标识符。
PREFER      使用小写的驼峰命名constant常量名。
DO          大于两个字母长的,使用首字母缩写和简写。
DON’T       不要对非私有标识符使用下划线。
DON’T       不要使用前缀字母。

4.1.2 排序

DO          把“dart:”的import放在其他import之前。
DO          在“package:”的import放在相关引入之前。
PREFER      最好把外部引入的包放在其他包之前。
DO          讲所有Export导出的单独放在所有import引入的区域之后。
DO          按字母顺序import引入的区域。

4.1.3 格式化

DO            使用dartfmt格式化代码。
CONSIDER      考虑更改代码,使其更适合格式化程序。
AVOID.        每行不超过80个字符。
DO            请对所有流控制语句使用大括号。

4.2 文档

4.2.1 注释

DO          把注释格式化成句子。
DON’T       不要对文档使用块注释。

4.2.2 文档注释

DO        对成员和类型使用 doc注释。///这是doc注释
PREFER    最好为公共api编写doc注释。
CONSIDER  考虑编写库级文档注释。
CONSIDER  考虑为私有api编写doc注释。
DO        注释要从一句总结的话开始。
DO        把文档注释的第一句总结话和下面的详情内容用一个空行隔开。
AVOID     注释应避免重复。
PREFER    最好用第三人称动词来注释函数或方法。
PREFER    最好用名词短语来注释变量、getter或setter
PREFER    最好用名词短语来注释库或类型。
CONSIDER  考虑在文档注释中包含代码示例。
DO        在doc注释中使用方括号引用标识符。///[userName]是用户名
DO        使用散文形式来解释参数、返回值和异常。
DO        文档注释要在代码注释之前

4.2.3 markdown

AVOID     避免过度使用markdown
AVOID     避免使用HTML格式
PREFER    doc注释中写代码示例时,使用```把代码包住

4.2.4 书写

PREFER    简洁!
AVOID     避免使用缩写和首字母缩略词,除非它们被大家熟知
PREFER    最好使用“this”而不是“the”来引用成员的实例 ///中文注释请忽略这一条。

未完继续

4.3 用法

4.3.1 库

DO use strings in part of directives.
DON’T import libraries that are inside the src directory of another package.
PREFER relative paths when importing libraries within your own package’s lib directory.

4.3.2 布尔值

DO use `??` to convert `null` to a boolean value

4.3.3 Strings

DO use adjacent strings to concatenate string literals.
PREFER using interpolation to compose strings and values.
AVOID using curly braces in interpolation when not needed.

4.3.4 Collections

DO use collection literals when possible.
DON’T use .length to see if a collection is empty.
CONSIDER using higher-order methods to transform a sequence.
AVOID using Iterable.forEach() with a function literal.
DON’T use List.from() unless you intend to change the type of the result.
DO use whereType() to filter a collection by type.
DON’T use cast() when a nearby operation will do.
AVOID using cast().

4.3.5 Functions

DO use a function declaration to bind a function to a name.
DON’T create a lambda when a tear-off will do.

4.3.6 Parameters

DO use = to separate a named parameter from its default value.
DON’T use an explicit default value of null.

4.3.7 Variables

DON’T explicitly initialize variables to null.
AVOID storing what you can calculate.

4.3.8 Members

DON’T wrap a field in a getter and setter unnecessarily.
PREFER using a final field to make a read-only property.
CONSIDER using => for simple members.
DON’T use this. except to redirect to a named constructor or to avoid shadowing.
DO initialize fields at their declaration when possible.

4.3.9 Constructors

DO use initializing formals when possible.
DON’T type annotate initializing formals.
DO use ; instead of {} for empty constructor bodies.
DON’T use new.
DON’T use const redundantly.

4.3.10 Error handling

AVOID catches without on clauses.
DON’T discard errors from catches without on clauses.
DO throw objects that implement Error only for programmatic errors.
DON’T explicitly catch Error or types that implement it.
DO use rethrow to rethrow a caught exception.

4.3.11 Asynchrony

PREFER async/await over using raw futures.
DON’T use async when it has no useful effect.
CONSIDER using higher-order methods to transform a stream.
AVOID using Completer directly.
DO test for Future when disambiguating a FutureOr whose type argument could be Object.

4.4 Design

4.4.1 Names

DO use terms consistently.
AVOID abbreviations.
PREFER putting the most descriptive noun last.
CONSIDER making the code read like a sentence.
PREFER a noun phrase for a non-boolean property or variable.
PREFER a non-imperative verb phrase for a boolean property or variable.
CONSIDER omitting the verb for a named boolean parameter.
PREFER the “positive” name for a boolean property or variable.
PREFER an imperative verb phrase for a function or method whose main purpose is a side effect.
PREFER a noun phrase or non-imperative verb phrase for a function or method if returning a value is its primary purpose.
CONSIDER an imperative verb phrase for a function or method if you want to draw attention to the work it performs.
AVOID starting a method name with get.
PREFER naming a method to___() if it copies the object’s state to a new object.
PREFER naming a method as___() if it returns a different representation backed by the original object.
AVOID describing the parameters in the function’s or method’s name.
DO follow existing mnemonic conventions when naming type parameters.

4.4.2 Libraries

PREFER making declarations private.
CONSIDER declaring multiple classes in the same library.

4.4.3 Classes and mixins

AVOID defining a one-member abstract class when a simple function will do.
AVOID defining a class that contains only static members.
AVOID extending a class that isn’t intended to be subclassed.
DO document if your class supports being extended.
AVOID implementing a class that isn’t intended to be an interface.
DO document if your class supports being used as an interface.
DO use mixin to define a mixin type.
AVOID mixing in a type that isn’t intended to be a mixin.

4.4.4 Constructors

CONSIDER making your constructor const if the class supports it.

4.4.5 Members

PREFER making fields and top-level variables final.
DO use getters for operations that conceptually access properties.
DO use setters for operations that conceptually change properties.
DON’T define a setter without a corresponding getter.
AVOID returning null from members whose return type is bool, double, int, or num.
AVOID returning this from methods just to enable a fluent interface.

4.4.6 Types

PREFER type annotating public fields and top-level variables if the type isn’t obvious.
CONSIDER type annotating private fields and top-level variables if the type isn’t obvious.
AVOID type annotating initialized local variables.
AVOID annotating inferred parameter types on function expressions.
AVOID redundant type arguments on generic invocations.
DO annotate when Dart infers the wrong type.
PREFER annotating with dynamic instead of letting inference fail.
PREFER signatures in function type annotations.
DON’T specify a return type for a setter.
DON’T use the legacy typedef syntax.
PREFER inline function types over typedefs.
CONSIDER using function type syntax for parameters.
DO annotate with Object instead of dynamic to indicate any object is allowed.
DO use Future as the return type of asynchronous members that do not produce values.
AVOID using FutureOr as a return type.

4.4.7 Parameters

AVOID positional boolean parameters.
AVOID optional positional parameters if the user may want to omit earlier parameters.
AVOID mandatory parameters that accept a special “no argument” value.
DO use inclusive start and exclusive end parameters to accept a range.

4.4.8 Equality

DO override hashCode if you override ==.
DO make your == operator obey the mathematical rules of equality.
AVOID defining custom equality for mutable classes.
DON’T check for null in custom == operators.

你可能感兴趣的:(Effective Dart - Dart语言的高效之路)