## 注釋
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
)
~~~