Flutter学习之Dart语言注释

代码注释是开发过程中必不可少的一个过程,那么,我们在进行Flutter开发时,怎么去进行文档注释呢?
这篇文章的主旨就是Flutter所使用的dart语言注释学习。

Dart支持单行注释, 多行注释和文档注释

1.单行注释

单行注释以//开头, Dart编译器会忽略//和行尾之间的所有内容

say() {
    // TODO: say something
    print('Hello dart!');
  }
2.多行注释

多行注释以 /* 开头,以 / 结尾, Dart编译器忽略 / 和 */ 之间的所有内容(除非注释是文档注释), 多行注释可以嵌套

sayWhat(String what) {
    /*
    * Say something
    * */
    print(what);
  }
3.文档注释

文档注释是以 ///或 /** 开头的多行或单行注释, 在连续行上使用 /// 与多行文档注释具有相同的效果。

在文档注释中,Dart编译器忽略所有文本,除非它括在括号中。 使用括号,您可以引用类,方法,字段,顶级变量,函数和参数。 括号中的名称在已记录的程序元素的词法范围内得到解析。

/// Dart class
///
/// TODO: Say hello to dart
class Dart {
  /// Say hello to dart
  say() {
    // TODO: say something
    print('Hello dart!');
  }

  /// Say something to dart
  /// The string [what] is what you want to say.
  sayWhat(String what) {
    /*
    * Say something
    * */
    print(what);
  }
}

Windows10+Flutter环境下我们使用dart sdk的文档生成工具来生成文档(dartdoc的Github地址),dartdoc.bat位于

XXX\dart-sdk\bin
dartdoc

从Flutter项目的根目录运行dartdoc, 文档目录会根据flutter项目的目录的lib下进行生成

Dartdoc.png

我们可以看到生成的文档放在了目录

项目目录\doc\api 
Directory.png

用浏览器打开自定义类的注解为

DartClass.png
4.高效Dart注释
  • 注释
  • 文档注释
  • Markdown
  • 写注释

在编写代码时, 很容易认为自己的代码已经写得很清楚,但是没有意识到已经依赖脑海中的上下文,如果另一个人接手你的代码的话,或者代码写完一段时间后再回顾的话,一段简明扼要的注释是非常重要的,可以节省大量时间,因此下面这里有一些提高dart开发的注释窍门。

  • 注释

    注释句子化

    避免使用块注释

  • 文档注释

    使用 /// 注释成员和类型

    优先为public的接口编写注释

    考虑写一个库级别的文档注释

    考虑为private的接口编写文档注释

    文档开头尽量用单句总结

    分离文档注释的第一句到自己的段落中

    避免与周围上下文冗余

    优先使用第三人称动词注释函数或方法

    优先使用名词短语注释变量, getter或setter

    优先使用名词短语注释库或者类型

    考虑使用代码示例注释

    尽量在文档注释中使用方括号来引用范围内标识符

    尽量简约地注释参数, 返回值和异常

    尽量在元数据注释之前加上文档注释

  • Markdown
    避免过度使用markdown

    避免使用HTML进行格式化

    优先使用反括号来隔开代码块

  • 写注释
    简短优先

    避免使用缩写词和缩写词

    首选使用“this”而不是“the”来引用成员实例

注释

以下提示适用于你不希望包含在生成的文档中的注释

注释句子化
// Not if there is nothing before it.
if (_chunks.isEmpty) return false;

针对英文:第一个字母需大写,除非它是区分大小写的标识符, 且需要使用句号,或者!或者?结束句子,所有注释都需如此:文档注释,内联内容,甚至是TODO。

中文: 尽量用一句简明扼要的话注释

避免使用块注释
greet(name) {
  // Assume we have a valid name.
  print('Hi, $name!');
}

下面为不推荐示范:

greet(name) {
  /* Assume we have a valid name. */
  print('Hi, $name!');
}

推荐使用(/ * ... * /)注释代码,其他文字注释应该使用//

文档注释

文档注释特别方便,因为dartdoc命令可以解析并生成好看的文档页。文档注释是任何出现在声明之前的注释,dartdoc会查找使用 /// 标记的注释

使用 /// 注释成员和类型

Linter规则:slash_for_doc_comments
使用文档注释 /// 而不是常规的注释使执行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 => ...

由于历史原因,dartdoc支持doc comments的两种语法:///(“C#style”)和/ ** ... * /(“JavaDoc style”),我们更喜欢///,因为它更紧凑。 / /将两条无内容行添加到多行文档注释中。 在某些情况下,///语法也更容易阅读,例如当doc注释包含使用标记列表项的项目符号列表时。

如果您偶然发现仍使用JavaDoc样式的代码,请考虑清理它。

优先为public的接口编写注释

Linter 规则: package_api_docs, public_member_api_docs

不必记录每个库,顶级变量,类型和成员,但应该注释其中的大多数。

考虑写一个库级别的文档注释

与Java这样的语言不同,类是程序组织中的唯一单元,但是在Dart中,库本身就是用户直接使用,导入和思考的实体。 这使得库指令成为文档注释的好地方,可以向读者介绍其中提供的主要概念和功能。 考虑包括:

  • 关于库用途的单句摘要。
  • 整个库使用的术语解释。
  • 一些使用API完成的完整代码示例。
  • 链接到(即库中使用的)最重要或最常用的类和函数。
  • 链接到(即库中使用的)库所关注的域上的外部引用。

你可以通过在文件开头的库指令上方放置doc注释来记录库。 如果库没有库指令,您可以添加一个只是挂起文档注释。

考虑为private的接口编写文档注释

Doc comments aren’t just for external consumers of your library’s public API. They can also be helpful for understanding private members that are called from other parts of the library.

文档注释不仅适用于库的公共API, 同样有助于理解从库的其他部分调用的私有成员。

文档开头尽量用单句总结

开始以句号结尾的简短的,以用户为中心的注释文档。 句子片段通常就足够了,为读者提供足够的上下文来定位自己,并决定是否应该继续阅读或寻找解决问题的方法。

/// 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) {
  ...
}

简而言之就是尽量简明扼要

分离文档注释的第一句到自己的段落中

在第一句之后添加一个空行,将其拆分为自己的段落。 如果多于一句解释是有用的,请将其余部分放在后面的段落中。
这有助于您编写一个简短的第一句话来总结文档。 此外,像Dartdoc这样的工具使用第一段作为类和列表列表等地方的简短摘要。

/// 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) {
 ...
}

简而言之即第一行说明该方法或类的主要功能,然后空一行,在进行详细描述或者参数等解释

避免与周围上下文冗余

读者可以从文档注释中清楚地看到类的名称,它实现的接口等。当读到成员的文档注释时,签名就在那里,而封闭的类是显而易见的。 这些都不需要在文档注释中拼写出来。 相反,专注于解释读者不知道的内容。

class RadioButtonWidget extends Widget {
 /// Sets the tooltip to [lines], which should have been word wrapped using
 /// the current font.
 void tooltip(List<String> lines) {
   ...
 }
}

下面为不推荐示范:

class RadioButtonWidget extends Widget {
  /// Sets the tooltip for this radio button widget to the list of strings in
  /// [lines].
  void tooltip(List<String> lines) {
    ...
  }
}

上面第一段注释清除地说明了该函数的使用目的,而下面不推荐的示例,则与上下文冗余了,"for this radio button widget"。

优先使用第三人称动词注释函数或方法

文档注释应该关注代码的作用

/// 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

文档注释应该强调属性是什么, 即使对于可能进行计算或其他工作的也是如此。 读者应该关心的是这段代码的结果,而不是代码本身。

/// The current day of the week, where `0` is Sunday.
int weekday;

/// The number of checked buttons on the page.
int get checkedCount => ...
优先使用名词短语注释库或者类型

类的文档注释通常是程序中最重要的部分,它们描述了类型的不变性,建立了它使用的术语,并为类的成员提供了其他文档注释的上下文,在这里做一点额外的努力可以让其他成员更容易记录

/// A chunk of non-breaking output text terminated by a hard or soft newline.
///
/// ...
class Chunk { ... }

简而言之就是多用专业术语,让注释看起来高大上

考虑使用代码示例注释
/// Returns the lesser of two numbers.
///
/// ```dart
/// min(5, 3) == 3
/// ```
num min(num a, num b) => ...

人类非常善于从示例中进行概括,因此即使是单个代码示例也可以使API更容易学习

尽量在文档注释中使用方括号来引用范围内标识符。

Linter规则: comment_references
如果在方括号中包含变量,方法或类型名称等内容,则dartdoc会查找名称并链接到相关的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 ...
尽量简约地注释参数, 返回值和异常

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) => ...

下面为不推荐示范:
其他语言使用详细标记和部分来描述方法的参数和返回值。

/// 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) => ...

好吧,作为一个常年使用java开发的中国Androider, 我更偏向于使用第二种方式

尽量在元数据注释之前加上文档注释
/// 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

你可以在文档注释中使用大多数markdown格式,dartdoc将使用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

可以看到使用了很多markdown语法注释

避免过度使用markdown

如有疑问,请格式化。 存在格式化以阐明您的内容,而不是替换它。 words很重要

避免使用HTML进行格式化

在极少数情况下使用它可能很有用,例如表格,但在几乎所有情况下,如果它在Markdown中过于复杂,你最好不要表达它。

优先使用反括号来隔开代码块

Markdown有两种表示代码块的方法:在每行上压缩代码四个空格,或者用反引号code表示。 当在缩进已经有意义的Markdown列表或代码块本身包含缩进代码的内容中使用时,前一种语法很脆弱,意思就是使用markdown注释时,前面已经使用了缩进,但是现在再使用缩进表示代码的话,会显得不好阅读

反引号语法避免了那些缩进问题,让您指出代码的语言,并且与使用内联代码的反引号一致。

/// You can use [CodeBlockExample] like this:
///
/// ```
/// var example = CodeBlockExample();
/// print(example.isItGreat); // "Yes."
/// ```

下面为不推荐示范:

/// You can use [CodeBlockExample] like this:
///
///     var example = CodeBlockExample();
///     print(example.isItGreat); // "Yes."

这里总结一下什么情况使用markdown注释比较好:
1.注释类时,该类功能需要目录说明
2.示例代码比较多的时候
3.需要列表说明功能的时候

写注释

在开始写注释的时候,无论我们使用的是中文还是英文,我觉得都得有一个写注释的习惯,因为这关系到以后的个人代码回顾,和别人阅读你的代码的时候的难易程度。

简短优先

要清晰准确,但也要简洁。

避免使用缩写词和缩写词

对于英文来说:许多人不知道“ie”,“eg”和“et al”是什么意思,你确信你所在领域的每个人都知道这个首字母缩略词可能并不像你想象的那么广为人知

对于中文来说:个人觉得缩写词应该会用得比较少

首选使用“this”而不是“the”来引用成员实例

记录类的成员时,通常需要返回调用该成员的对象,使用“the”可能含糊不清

class Box {
  /// The value this wraps.
  var _value;

  /// True if this box contains a value.
  bool get hasValue => _value != null;
}

Dart语言之旅:https://www.dartlang.org/guides/language/language-tour#comments

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容