## 注释
Go提供了C风格的块注释`/* */`和C++风格的行注释`//`。通常为行注释;块注释大多数作为程序包的注释,但也可以用于一个表达式中,或者用来注释掉一大片代码。
程序—同时又是网络服务器—`godoc`,用来处理Go源文件,抽取有关程序包内容的文档。在顶层声明之前出现,并且中间没有换行的注释,会随着声明一起被抽取,作为该项的解释性文本。这些注释的本质和风格决定了`godoc`所产生文档的质量。
每个程序包都应该有一个*包注释*,一个位于package子句之前的块注释。对于有多个文件的程序包,包注释只需要出现在一个文件中,任何一个文件都可以。包注释应该用来介绍该程序包,并且提供与整个程序包相关的信息。它将会首先出现在`godoc`页面上,并会建立后续的详细文档。
~~~
/*
Package regexp implements a simple library for regular expressions.
The syntax of the regular expressions accepted is:
regexp:
concatenation { '|' concatenation }
concatenation:
{ closure }
closure:
term [ '*' | '+' | '?' ]
term:
'^'
'$'
'.'
character
'[' [ '^' ] character-ranges ']'
'(' regexp ')'
*/
package regexp
~~~
如果程序包很简单,则包注释可以非常简短。
~~~
// Package path implements utility routines for
// manipulating slash-separated filename paths.
~~~
注释不需要额外的格式,例如星号横幅。生成的输出甚至可能会不按照固定宽度的字体进行展现,所以不要依靠用空格进行对齐—`godoc`,就像`gofmt`,会处理这些事情。注释是不作解析的普通文本,所以HTML和其它注解,例如`_this_`,将会*逐字的*被复制。对于缩进的文本,`godoc`确实会进行调整,来按照固定宽度的字体进行显示,这适合于程序片段。[`fmt` package](http://golang.org/pkg/fmt/)的包注释使用了这种方式来获得良好的效果。
根据上下文,`godoc`甚至可能不会重新格式化注释,所以要确保它们看起来非常直接:使用正确的拼写,标点,以及语句结构,将较长的行进行折叠,等等。
在程序包里面,任何直接位于顶层声明之前的注释,都会作为该声明的*文档注释*。程序中每一个被导出的(大写的)名字,都应该有一个文档注释。
文档注释作为完整的语句可以工作的最好,可以允许各种自动化的展现。第一条语句应该为一条概括语句,并且使用被声明的名字作为开头。
~~~
// Compile parses a regular expression and returns, if successful, a Regexp
// object that can be used to match against text.
func Compile(str string) (regexp *Regexp, err error) {
~~~
如果都是使用名字来起始一个注释,那么就可以通过`grep`来处理`godoc`的输出。设想你正在查找正规表达式的解析函数,但是不记得名字“Compile”了,那么,你运行了命令
~~~
$ godoc regexp | grep parse
~~~
如果程序包中所有的文档注释都起始于"This function...",那么`grep`将无法帮助你想起这个名字。但是,因为程序包是使用名字来起始每个文档注释,所以你将会看到类似这样的信息,这将使你想起你要查找的单词。
~~~
$ godoc regexp | grep parse
Compile parses a regular expression and returns, if successful, a Regexp
parsed. It simplifies safe initialization of global variables holding
cannot be parsed. It simplifies safe initialization of global variables
$
~~~
Go的声明语法允许对声明进行组合。单个的文档注释可以用来介绍一组相关的常量或者变量。由于展现的是整个声明,这样的注释通常非常肤浅。
~~~
// Error codes returned by failures to parse an expression.
var (
ErrInternal = errors.New("regexp: internal error")
ErrUnmatchedLpar = errors.New("regexp: unmatched '('")
ErrUnmatchedRpar = errors.New("regexp: unmatched ')'")
...
)
~~~
分组还可以用来指示各项之间的关系,例如一组实际上由一个互斥进行保护的变量。
~~~
var (
countLock sync.Mutex
inputCount uint32
outputCount uint32
errorCount uint32
)
~~~