如何阅读指南
-
DO
应始终遵循的准则 -
DON'T
不应该这么使用的准则 -
PREFER
应该遵循的准则,但是在某些情况下,可以根据个人理解忽略,不遵循 -
DON'T
不应该这么使用的准则 -
AVOID
不应该遵循的准则,但是在某些情况下,可以根据个人理解忽略,不遵循 -
CONSIDER
可遵循或者不遵循的规则,取决于个人偏好
注释
DO 格式化注释,例如句子
将第一个字母大写,除非它是区分大小写的标识符。用句号结束它(或者可能是“!”或“?”)。所有注释都是如此:文档注释,内联注释,甚至是TODO,即使它是一个句子片段。
// Not if there is nothing before it.
if (_chunks.isEmpty) return false;
DON’T 将注释写在文档中
// Good
greet(name) {
// Assume we have a valid name.
print('Hi, $name!');
}
// Bad
greet(name) {
/* Assume we have a valid name. */
print('Hi, $name!');
}
您可以使用块注释(/* ... */)
暂时注释掉一段代码,但所有其他注释都应该使用//
Doc 注释
Doc 注释的内容会被解析生成doc提示文档块,类似代码的信息提示块
DO 使用 /// 表示doc注释记录成员和类型
Linter规则:slash_for_doc_comments
/// The number of characters in this chunk when unsplit. 未拆分时此块中的字符数
int get length => ...
如果在文档注释中使用了项目符号列表,使用*
标记列表项。
/// 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) {
// ...
}
PREFER 为公共API编写doc注释
Linter规则:package_api_docs, public_member_api_docs
您不必记录每个库,顶级变量,类型和成员进行注释,但您应记录其中的大多数。
CONSIDER 编写库级文档评论
在library指令之前为文档编写doc 注释,可以向读者介绍其中提供的主要概念和功能。考虑包括:
- 关于库用途的单句摘要。
- 整个库使用的术语解释。
- 一些使用API的完整代码示例。
- 指向最重要或最常用的类和函数的链接
- 指向库所关心的域上的外部引用的链接
CONSIDER 为私有API编写doc注释
Doc注释不仅适用于库的公共API的外部使用者,它们还有助于理解从库的其他部分调用的私有成员。
DO 用单句摘要开始文档评论
使用以句号结尾的简明的注释
开始编写文档注释,为读者提供足够的上下文来定位自己,并决定是否应该继续阅读或寻找解决问题的方法
// Good
/// 从文件系统中删除[path]中的文件
void delete(String path) {
...
}
// Bad
/// 根据文件系统的状态和用户的权限,
/// 可能会或可能不会执行某些操作。如果
/// [path]中没有文件或无法访问该文件,则此函数将分别抛出[IOError]
/// 或[PermissionError]。否则,这将删除该文件。
void delete(String path) {
...
}
DO 将文档评论的第一句作为一个独立的段落
在第一句之后添加一个空行,将其拆分为独立的段落。如果多于一句解释是有用的,请将其余部分放在后面的段落中。这有助于您编写一个简短的第一句话来总结文档。
// Good
// Deletes the file at [path].
///
/// Throws an [IOError] if the file could not be found. Throws a
/// [PermissionError] if the file is present but could not be deleted.
void delete(String path) {
...
}
// Bad
/// Deletes the file at [path]. Throws an [IOError] if the file could not
/// be found. Throws a [PermissionError] if the file is present but could
/// not be deleted.
void delete(String path) {
...
}
AVOID 与周围环境的冗余
类的doc注释的读者可以清楚地看到类的名称,它实现的接口等。当读取成员的注释文档时,签名和封闭的类是显而易见的。这些都不需要在文档评论中拼写出来,只专注于解释读者不知道的内容。
// Good
class RadioButtonWidget extends Widget {
/// Sets the tooltip to [lines], which should have been word wrapped using
/// the current font.
void tooltip(List<String> lines) {
...
}
}
// Bad
class RadioButtonWidget extends Widget {
/// Sets the tooltip for this radio button widget to the list of strings in
/// [lines].
void tooltip(List<String> lines) {
...
}
}
PREFER 启动函数或方法注释与第三人称动词
文档注释应该关注代码的作用
/// Returns `true` if every element satisfies the [predicate].如果每个元素都满足[predicate],则返回“true”
bool all(bool predicate(T element)) => ...
/// Starts the stopwatch if not already running. 如果尚未运行,则启动秒表
void start() {
...
}
PREFER 使用用名词短语注释变量、getter或setter
doc注释应该强调属性是什么。即使对于可能进行计算或其他工作的getter也是如此。调用者关心的是工作的结果,而不是工作本身。
/// The current day of the week, where `0` is Sunday.
int weekday;
/// The number of checked buttons on the page.
int get checkedCount => ...
PREFER 对库或者类型注释使用名词短语
类Doc注释通常是程序中最重要的文档。它们描述了类型的不变量,建立了它使用的术语,并为类的成员提供了其他文档注释的上下文。在这里做一点额外的努力可以使所有其他成员更容易记录
/// A chunk of non-breaking output text terminated by a hard or soft newline.由硬或软换行符终止的一大块非破坏输出文本
///
/// ...
class Chunk { ... }
CONSIDER 文档注释中代码示例
/// Returns the lesser of two numbers.
///
/// ```dart
/// min(5, 3) == 3
/// ```
num min(num a, num b) => ...
DO 使用方括号来引用范围内标识符
如果在方括号中包含变量,方法或类型名称等内容,则dartdoc会查找名称并链接到相关的API文档。括号是可选的,但使用它可以在引用方法或构造函数时更清晰
/// Throws a [StateError] if ... 抛出[StateError] if
/// similar to [anotherMethod()], but ... 类似于[anotherMethod ()],但是......
要链接到特定类的成员,请使用以点分隔的类名和成员名:
/// Similar to [Duration.inDays], but handles fractional days. 与[Duration.inDays]类似,但...
点语法也可用于引用命名构造函数。对于未命名的构造函数,在类名后面加上括号:
/// To create a point, call [Point()] or use [Point.polar()] to ...要创建一个点,请调用[Point()]或使用[Point.polar()]来...
DO 用平实的语句来解释参数、返回值和异常。
其他语言使用详细标记和部分来描述方法的参数和返回值,即将其描述集成到方法的描述中,并使用方括号突出显示参数。
// Good
/// Defines a flag. 定义一个标志
///
/// Throws an [ArgumentError] if there is already an option named [name] or 如果已经有一个名为[name]的选项或
/// there is already an option using abbreviation [abbr]. Returns the new flag. 已经有一个使用缩写[abbr]的选项,则抛出[ArgumentError ]。返回新标志
Flag addFlag(String name, String abbr) => ...
// Bad
/// Defines a flag with the given name and abbreviation.定义具有给定名称和缩写的标志
///
/// @param name The name of the flag. @param name标志的名称
/// @param abbr The abbreviation for the flag.
/// @returns The new flag.
/// @throws ArgumentError If there is already an option with
/// the given name or abbreviation.
Flag addFlag(String name, String abbr) => ...
DO 在元数据注释之前放置文档注释
//Good
/// A button that can be flipped on and off. 可以打开和关闭的按钮。
@Component(selector: 'toggle')
class ToggleComponent {}
// Bad
@Component(selector: 'toggle')
/// A button that can be flipped on and off.
class ToggleComponent {}
Markdown
您可以在文档注释中使用大多数markdown格式,dartdoc将使用markdown包相应地处理它。
有很多指南已经向您介绍Markdown。它普遍受欢迎是我们选择它的原因。这里只是一个简单的例子,让您了解所支持的内容:
/// This is a paragraph of regular text.
///
/// This sentence has *two* _emphasized_ words (italics) and **two**
/// __strong__ ones (bold).
///
/// A blank line creates a separate paragraph. It has some `inline code`
/// delimited using backticks.
///
/// * Unordered lists.
/// * Look like ASCII bullet lists.
/// * You can also use `-` or `+`.
///
/// 1. Numbered lists.
/// 2. Are, well, numbered.
/// 1. But the values don't matter.
///
/// * You can nest lists too.
/// * They must be indented at least 4 spaces.
/// * (Well, 5 including the space after `///`.)
///
/// Code blocks are fenced in triple backticks:
///
/// ```
/// this.code
/// .will
/// .retain(its, formatting);
/// ```
///
/// The code language (for syntax highlighting) defaults to Dart. You can
/// specify it by putting the name of the language after the opening backticks:
///
/// ```html
/// <h1>HTML is magical!</h1>
/// ```
///
/// Links can be:
///
/// * http://www.just-a-bare-url.com
/// * [with the URL inline](http://google.com)
/// * [or separated out][ref link]
///
/// [ref link]: http://google.com
///
/// # A Header
///
/// ## A subheader
///
/// ### A subsubheader
///
/// #### If you need this many levels of headers, you're doing it wrong
AVOID 过度使用markdown
如有疑问,请格式化。使用格式化以阐明您的内容,而不是替换它。
AVOID 使用HTML进行格式化
在极少数情况下使用它可能很有用,例如表格,但在几乎所有情况下,如果它在Markdown中过于复杂,你最好不要表达它。
PREFER 代码块使用```
// Good
/// You can use [CodeBlockExample] like this:
///
/// ```
/// var example = CodeBlockExample();
/// print(example.isItGreat); // "Yes."
/// ```
// Bad
/// You can use [CodeBlockExample] like this:
///
/// var example = CodeBlockExample();
///
PREFER 简洁
要清晰准确,但也要简洁
AVOID 缩写和首字母缩略词,除非它们是显而易见的
许多人不知道“ie”,“eg”和“et al。”是什么意思。你确信你所在领域的每个人都知道这个首字母缩略词可能并不像你想象的那么广为人知。
PREFER 首先使用“this”而不是“the”来引用成员的实例
记录类的成员时,通常需要返回调用该成员的对象。使用“the”可能含糊不清。
class Box {
/// The value this wraps.
var _value;
/// True if this box contains a value.
bool get hasValue => _value != null;
}