文档注释参考
最后更新于:2022-04-02 05:54:46
[TOC]
你今天可能觉得你的代码很容易看懂,是显而易见的。但是你忽略了你已经在自己的脑海中构建了依赖的上下文关系。但是对于其他人去看你的代码,或者是隔了很久之后你自己去查看自己的代码,都不会有这样已经建立在脑海中的上下文关系。这个时候如果是有代码注释可能会节省更多的时间。往往我们花很少的时间就能完成代码注释。
我们都知道代码应该是自文档化的,并不是所有的注释都是有用的。但现实是,我们中的大多数人并没有写出我们应该写的那么多注释。这就像锻炼:你在技术上可以做得太多,但更有可能你做得太少了。试着提高它。
## 注释
以下技巧适用于您不希望包含在生成文档中的注释。
### 要像句子一样格式化评论。
~~~
// Not if there is nothing before it.
if (_chunks.isEmpty) return false;
~~~
除非是区分大小写的标识符,否则第一个单词要大写。以句号结尾(或“!”或“?”)。对于所有的注释都是如此:doc注释、内联内容,甚至TODOs。即使是一个句子片段。
### 不要在文档中使用块注释。
~~~
greet(name) {
// Assume we have a valid name.
print('Hi, $name!');
}
~~~
以下是错误示例。
~~~
greet(name) {
/* Assume we have a valid name. */
print('Hi, $name!');
}
~~~
你可以使用块注释(/*…*/)临时注释掉一段代码,但是所有其他注释都应该使用//。
## Doc注释
Doc注释特别方便,因为dartdoc解析它们并从中生成漂亮的Doc页面。doc注释是任何出现在声明前并使用特殊///语法的注释。
### 使用///文档注释来记录成员和类型。
使用doc注释而不是常规注释,可以让dartdoc找到并生成文档。
~~~
/// The number of characters in this chunk when unsplit.
int get length => ...
~~~
以下是错误示例。
~~~
// The number of characters in this chunk when unsplit.
int get length => ...
~~~
由于历史原因,达特茅斯学院支持道格评论的两种语法:///(“C#风格”)和/**…* /(“JavaDoc风格”)。我们更喜欢/// 因为它更紧凑。/\*\*和*/在多行文档注释中添加两个无内容的行。在某些情况下,///语法也更容易阅读,例如文档注释包含使用*标记列表项的项目符号列表。
如果您发现代码仍然使用JavaDoc样式,请考虑清理它。
### 优先为公共api编写文档注释。
您不必为每个库、顶级变量、类型和成员编制文档,但您应该为它们中的大多数编制文档。
### 考虑写一个库级别的文档注释
与Java等语言不同,在Dart中,类是程序组织的唯一单位,库本身是用户直接使用、导入和思考的实体。这使得library directive提供了一个很好的文档空间,向读者介绍了库中提供的主要概念和功能。考虑包括:
* 用一句话概括库的用途。
* 解释整个库使用的术语。
* 两个完整的代码示例使用API遍历。
* 链接到最重要或最常用的类和函数。
* 链接到与库有关的领域的外部引用。
您可以通过在文件开头的库指令上方放置一个doc注释来记录一个库。如果库没有一个库指令,你可以添加一个来挂掉文档注释。
### 考虑为私有api编写文档注释。
Doc注释并不仅仅针对库的公共API的外部使用者。它们还有助于理解从库的其他部分调用的私有成员。
### 用一句话总结开始doc注释。
以简短的、以用户为中心的描述开始你的文档注释,以句号结尾。一个句子片段通常就足够了。为读者提供足够的上下文,使他们能够确定自己的方向,并决定是否应该继续阅读或在别处寻找问题的解决方案。
~~~
/// Deletes the file at [path] from the file system.
void delete(String path) {
...
}
~~~
以下是错误示例。
~~~
/// Depending on the state of the file system and the user's permissions,
/// certain operations may or may not be possible. If there is no file at
/// [path] or it can't be accessed, this function throws either [IOError]
/// or [PermissionError], respectively. Otherwise, this deletes the file.
void delete(String path) {
...
}
~~~
### 一定要把“doc注释”的第一句话分隔成自己的段落。
在第一个句子之后添加一个空行,把它分成自己的段落。如果一个以上的解释是有用的,把其余的放在后面的段落。
这有助于您编写一个紧凑的第一句话,总结文档。同样,工具如达特茅斯学院使用第一段作为一个简短的总结,如类和成员列表。
~~~
/// 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) {
...
}
~~~
以下是错误示例。
~~~
/// 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) {
...
}
~~~
### 避免与周围的上下文冗余。
类文档注释的读者可以清楚地看到类的名称、它实现的接口等。这些都不需要在doc注释中说明。相反,要专注于解释读者还不知道的东西。
~~~
class RadioButtonWidget extends Widget {
/// Sets the tooltip to [lines], which should have been word wrapped using
/// the current font.
void tooltip(List lines) {
...
}
}
~~~
以下是错误示例。
~~~
class RadioButtonWidget extends Widget {
/// Sets the tooltip for this radio button widget to the list of strings in
/// [lines].
void tooltip(List lines) {
...
}
}
~~~
### 优先用第三人称动词开始函数或方法注释。
doc注释应该关注代码的功能。
~~~
/// Returns `true` if every element satisfies the [predicate].
bool all(bool predicate(T element)) => ...
/// Starts the stopwatch if not already running.
void start() {
...
}
~~~
### 优先用名词短语开始变量、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 => ...
~~~
避免在setter和getter上都有doc注释,因为dardoc只会显示一个注释(getter上的注释)。
### 优先从库开始,或者用名词短语输入注释。
类的文档注释通常是程序中最重要的文档。它们描述了类型的不变量,建立了它使用的术语,并为类的成员提供了其他文档注释的上下文。在这里做一点额外的工作可以使所有其他成员更容易记录。
~~~
/// A chunk of non-breaking output text terminated by a hard or soft newline.
///
/// ...
class Chunk { ... }
~~~
### 考虑在doc注释中包含代码示例。
~~~
/// Returns the lesser of two numbers.
///
/// ```dart
/// min(5, 3) == 3
/// ```
num min(num a, num b) => ...
~~~
人类擅长从示例中归纳,因此即使是一个代码示例也能使API更容易学习。
### 请务必在doc注释中使用方括号来引用范围内的标识符。
如果将变量、方法或类型名称放在方括号中,那么dardoc会查找名称并链接到相关的API文档。圆括号是可选的,但在引用方法或构造函数时可以使它更清楚。
~~~
/// Throws a [StateError] if ...
/// similar to [anotherMethod()], but ...
~~~
要链接到特定类的成员,使用类名和成员名,用点分隔:
~~~
/// Similar to [Duration.inDays], but handles fractional days.
~~~
点语法还可以用于引用指定的构造函数。对于未命名的构造函数,在类名后加括号:
~~~
/// To create a point, call [Point()] or use [Point.polar()] to ...
~~~
### 务必使用白话文来解释参数、返回值和异常。
其他语言使用详细标记和部分来描述方法的参数和返回值。
以下是错误示例:
~~~
/// Defines a flag with the given name and abbreviation.
///
/// @param name The name of the flag.
/// @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) => ...
~~~
Dart中的约定是将其集成到方法描述中,并使用方括号突出显示参数。
~~~
/// Defines a flag.
///
/// Throws an [ArgumentError] if there is already an option named [name] or
/// there is already an option using abbreviation [abbr]. Returns the new flag.
Flag addFlag(String name, String abbr) => ...
~~~
### 一定要在元数据注释之前加上doc注释。
~~~
/// A button that can be flipped on and off.
@Component(selector: 'toggle')
class ToggleComponent {}
~~~
以下是错误示例:
~~~
@Component(selector: 'toggle')
/// A button that can be flipped on and off.
class ToggleComponent {}
~~~
## 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
///
';