Contents

Effective Dart: Style

好的代码令人惊讶的重要部分是好的样式. 一致的命名,排序和格式有助于代码相同的外观相同. 它利用了我们大多数人在眼系统中拥有的强大的模式匹配硬件. 如果我们在整个Dart生态系统中使用一致的样式,那么这将使我们所有人更容易学习彼此的代码并做出贡献.

Identifiers

标识符在Dart中具有三种风格.

  • UpperCamelCase名称将每个单词的首字母大写,包括第一个字母.

  • lowerCamelCase名称为每个字的第一个字母, 除了第一个它总是小写,即使它是一个缩写.

  • lowercase_with_underscores仅使用小写字母(即使是首字母缩写词),并使用_分隔单词.

DO name types using UpperCamelCase.

短绒规则: camel_case_types

类,枚举,typedef和类型参数应将每个单词的首字母大写(包括第一个单词),并且不使用分隔符.

class SliderMenu { ... }

class HttpRequest { ... }

typedef Predicate<T> = bool Function(T value);

这甚至包括打算在元数据注释中使用的类.

class Foo {
  const Foo([arg]);
}

@Foo(anArg)
class A { ... }

@Foo()
class B { ... }

如果注释类的构造函数不带参数,则可能要为其创建一个单独的lowerCamelCase常量.

const foo = Foo();

@foo
class C { ... }

DO name extensions using UpperCamelCase.

短绒规则: camel_case_extensions

与类型一样,扩展名应大写每个单词的首字母(包括第一个单词),并且不使用分隔符.

extension MyFancyList<T> on List<T> { ... }

extension SmartIterable<T> on Iterable<T> { ... }

DO name libraries, packages, directories, and source files using lowercase_with_underscores.

林特规则: library_names, file_names

一些文件系统不区分大小写,因此许多项目要求文件名全部为小写. 使用分隔符可以使名称仍以该形式可读. 使用下划线作为分隔符可确保名称仍然是有效的Dart标识符,如果该语言以后支持符号导入,则可能会有所帮助.

library peg_parser.source_scanner;

import 'file_system.dart';
import 'slider_menu.dart';
library pegparser.SourceScanner;

import 'file-system.dart';
import 'SliderMenu.dart';

DO name import prefixes using 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;
import 'dart:math' as Math;
import 'package:angular_components/angular_components'
    as angularComponents;
import 'package:js/js.dart' as JS;

DO name other identifiers using lowerCamelCase.

Linter规则: non_constant_identifier_names

类成员,顶级定义,变量,参数和命名参数应将第一个单词以外的每个单词的第一个字母大写,并且不使用分隔符.

var item;

HttpRequest httpRequest;

void align(bool clearItems) {
  // ...
}

PREFER using lowerCamelCase for constant names.

Linter规则: constant_identifier_names

在新代码中,将lowerCamelCase用于常量变量,包括枚举值.

const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');

class Dice {
  static final numberGenerator = Random();
}
const PI = 3.14;
const DefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');

class Dice {
  static final NUMBER_GENERATOR = Random();
}

您可以使用SCREAMING_CAPS与现有代码保持一致,在以下情况下:

  • 将代码添加到已经使用SCREAMING_CAPS的文件或库中时.
  • 生成与Java代码并行的Dart代码时-例如,从protobufs生成的枚举类型.

DO capitalize acronyms and abbreviations longer than two letters like words.

大写的首字母缩写词可能很难阅读,并且多个相邻的首字母缩写词可能导致名称不明确. 例如,给定以HTTPSFTP开头的名称,则无法分辨它是指HTTPS FTP还是HTTP SFTP.

为避免这种情况,首字母缩写词和缩写词与普通单词一样大写,除了两个字母的首字母缩写词. (ID和Mr.等两个字母的缩写仍像单词一样大写.)

HttpConnectionInfo
uiHandler
IOStream
HttpRequest
Id
DB
HTTPConnection
UiHandler
IoStream
HTTPRequest
ID
Db

DON’T use a leading underscore for identifiers that aren’t private.

Dart在标识符中使用前导下划线将成员和顶级声明标记为私有. 这样可以培训用户将领先的下划线与其中一种声明相关联. 他们看到" _"并认为"私有".

对于局部变量,参数或库前缀,没有"专用"的概念. 当其中之一的名称以下划线开头时,它会向阅读器发送一个混乱的信号. 为避免这种情况,请勿在这些名称中使用前划线.

例外:未使用的参数可以命名为______等,这在诸如回调之类的事情中发生,在该回调中您可以向其传递一个值,但无需使用它. 给它一个包含下划线的名称是一种惯用的方式,用于指示未使用该值.

DON’T use prefix letters.

BCPL时代出现了匈牙利表示法和其他方案,当时编译器没有做很多事情来帮助您理解代码. 由于Dart可以告诉您声明的类型,范围,可变性和其他属性,因此没有理由在标识符名称中对这些属性进行编码.

defaultTimeout
kDefaultTimeout

Ordering

为了使文件的序言保持整洁,我们有一条应在指令中出现的规定顺序.每个"节"都应以空白行分隔.

一条短绒规则将处理所有排序准则: directives_ordering.

DO place “dart:” imports before other imports.

Linter规则: directives_ordering

import 'dart:async';
import 'dart:html';

import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

DO place “package:” imports before relative imports.

Linter规则: directives_ordering

import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

import 'util.dart';

PREFER placing external “package:” imports before other imports.

Linter规则: directives_ordering

如果您自己的软件包以及其他外部软件包有多个" package:"导入,请将您的软件包放在外部软件包之后的单独部分中.

import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

import 'package:my_package/util.dart';

DO specify exports in a separate section after all imports.

Linter规则: directives_ordering

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';

DO sort sections alphabetically.

Linter规则: directives_ordering

import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

import 'foo.dart';
import 'foo/foo.dart';
import 'package:foo/foo.dart';
import 'package:bar/bar.dart';

import 'foo/foo.dart';
import 'foo.dart';

Formatting

Like many languages, Dart ignores whitespace. However, humans don’t. Having a consistent whitespace style helps ensure that human readers see code the same way the compiler does.

DO format your code using dartfmt.

格式化是繁琐的工作,并且在重构期间特别耗时. 幸运的是,您不必担心. 我们提供了一个称为dartfmt的复杂的自动代码格式化程序 ,可以为您完成此任务. 我们有一些有关适用规则的文档 ,但是Dart的官方空白处理规则是dartfmt生成的 .

其余的格式指南仅适用于dartfmt无法为您解决的一些问题.

CONSIDER changing your code to make it more formatter-friendly.

The formatter does the best it can with whatever code you throw at it, but it can’t work miracles. If your code has particularly long identifiers, deeply nested expressions, a mixture of different kinds of operators, etc. the formatted output may still be hard to read.

发生这种情况时,请重新组织或简化代码. 考虑缩短局部变量名称或将表达式提升为新的局部变量. 换句话说,进行与您手工格式化代码并尝试使其更具可读性的修改方式相同的修改. 可以将dartfmt视为一种合作伙伴关系,在这种伙伴关系中,有时需要反复合作才能产生漂亮的代码.

AVOID lines longer than 80 characters.

短绒规则: lines_longer_than_80_chars

可读性研究表明,较长的文本行较难阅读,因为移至下一行的开始时,您的眼睛必须走得更远. 这就是报纸和杂志使用多列文字的原因.

如果您真的希望行长超过80个字符,那么我们的经验就是您的代码可能太冗长,并且可能更紧凑. 主要罪犯通常是VeryLongCamelCaseClassNames . 问问自己:"该类型名称中的每个单词是否都告诉我一些关键信息或防止名称冲突?"如果不是,请考虑将其省略.

请注意,dartfmt会为您完成99%的操作,但最后1%是您. 它不会将长字符串文字拆分为80列,因此您必须手动进行操作.

例外:当URI或文件路径出现在注释或字符串中(通常在导入或导出中)时,即使它导致行超过80个字符,它也可能保持完整. 这样可以更轻松地在源文件中搜索路径.

例外:多行字符串可以包含多于80个字符的行,因为换行符在字符串内很重要,将行拆分为较短的行可以更改程序.

DO use curly braces for all flow control statements.

Linter规则: curl_braces_in_flow_control_structures

这样做可以避免其他问题.

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

例外:如果您有一个if语句,其中没有else子句,并且整个if语句都适合一行,则可以根据需要省略花括号:

if (arg == null) return defaultValue;

但是,如果正文换行到下一行,请使用花括号:

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

by  ICOPY.SITE