Loading...
Loading...
Compare original and translation side by side
Normative: All top-level exported names must have doc comments.
规范性要求:所有顶层导出的名称必须包含文档注释。
// Good:
// A Request represents a request to run a command.
type Request struct { ...
// Encode writes the JSON encoding of req to w.
func Encode(w io.Writer, req *Request) { ...// Good:
// A Request represents a request to run a command.
type Request struct { ...
// Encode writes the JSON encoding of req to w.
func Encode(w io.Writer, req *Request) { ...// Good:
// Options configure the group management service.
type Options struct {
// General setup:
Name string
Group *FooGroup
// Dependencies:
DB *sql.DB
// Customization:
LargeGroupThreshold int // optional; default: 10
MinimumMembers int // optional; default: 2
}// Good:
// Options configure the group management service.
type Options struct {
// General setup:
Name string
Group *FooGroup
// Dependencies:
DB *sql.DB
// Customization:
LargeGroupThreshold int // optional; default: 10
MinimumMembers int // optional; default: 2
}Normative: Documentation comments must be complete sentences.
// Good:
// A Server handles serving quotes from Shakespeare.
type Server struct {
// BaseDir points to the base directory for Shakespeare's works.
//
// Expected structure:
// {BaseDir}/manifest.json
// {BaseDir}/{name}/{name}-part{number}.txt
BaseDir string
WelcomeMessage string // displayed when user logs in
ProtocolVersion string // checked against incoming requests
PageLength int // lines per page (optional; default: 20)
}规范性要求:文档注释必须是完整的句子。
// Good:
// A Server handles serving quotes from Shakespeare.
type Server struct {
// BaseDir points to the base directory for Shakespeare's works.
//
// Expected structure:
// {BaseDir}/manifest.json
// {BaseDir}/{name}/{name}-part{number}.txt
BaseDir string
WelcomeMessage string // displayed when user logs in
ProtocolVersion string // checked against incoming requests
PageLength int // lines per page (optional; default: 20)
}Advisory: Aim for ~80 columns, but no hard limit.
undefined建议性要求:目标长度约80列,但无硬性限制。
undefined
Break based on punctuation. Don't split long URLs.
---
根据标点换行,不要拆分长URL。
---Normative: Every package must have exactly one package comment.
// Good:
// Package math provides basic constants and mathematical functions.
//
// This package does not guarantee bit-identical results across architectures.
package math规范性要求:每个包必须且只能有一个包注释。
// Good:
// Package math provides basic constants and mathematical functions.
//
// This package does not guarantee bit-identical results across architectures.
package math// Good:
// The seed_generator command is a utility that generates a Finch seed file
// from a set of JSON study configs.
package mainBinary seed_generatorCommand seed_generatorThe seed_generator commandSeed_generator ...doc.go// Good:
// The seed_generator command is a utility that generates a Finch seed file
// from a set of JSON study configs.
package mainBinary seed_generatorCommand seed_generatorThe seed_generator commandSeed_generator ...doc.goAdvisory: Document error-prone or non-obvious parameters, not everything.
// Bad: Restates the obvious
// Sprintf formats according to a format specifier and returns the resulting string.
//
// format is the format, and data is the interpolation data.
func Sprintf(format string, data ...any) string
// Good: Documents non-obvious behavior
// Sprintf formats according to a format specifier and returns the resulting string.
//
// The provided data is used to interpolate the format string. If the data does
// not match the expected format verbs or the amount of data does not satisfy
// the format specification, the function will inline warnings about formatting
// errors into the output string.
func Sprintf(format string, data ...any) string建议性要求:仅文档化易出错或不明显的参数,无需全部说明。
// Bad: Restates the obvious
// Sprintf formats according to a format specifier and returns the resulting string.
//
// format is the format, and data is the interpolation data.
func Sprintf(format string, data ...any) string
// Good: Documents non-obvious behavior
// Sprintf formats according to a format specifier and returns the resulting string.
//
// The provided data is used to interpolate the format string. If the data does
// not match the expected format verbs or the amount of data does not satisfy
// the format specification, the function will inline warnings about formatting
// errors into the output string.
func Sprintf(format string, data ...any) stringAdvisory: Don't restate implied context behavior; document exceptions.
ctx.Err()// Bad: Restates implied behavior
// Run executes the worker's run loop.
//
// The method will process work until the context is cancelled.
func (Worker) Run(ctx context.Context) error
// Good: Just the essential
// Run executes the worker's run loop.
func (Worker) Run(ctx context.Context) error// Good: Non-standard cancellation behavior
// Run executes the worker's run loop.
//
// If the context is cancelled, Run returns a nil error.
func (Worker) Run(ctx context.Context) error
// Good: Special context requirements
// NewReceiver starts receiving messages sent to the specified queue.
// The context should not have a deadline.
func NewReceiver(ctx context.Context) *Receiver建议性要求:不要重复说明隐含的上下文行为;仅文档化例外情况。
ctx.Err()// Bad: Restates implied behavior
// Run executes the worker's run loop.
//
// The method will process work until the context is cancelled.
func (Worker) Run(ctx context.Context) error
// Good: Just the essential
// Run executes the worker's run loop.
func (Worker) Run(ctx context.Context) error// Good: Non-standard cancellation behavior
// Run executes the worker's run loop.
//
// If the context is cancelled, Run returns a nil error.
func (Worker) Run(ctx context.Context) error
// Good: Special context requirements
// NewReceiver starts receiving messages sent to the specified queue.
// The context should not have a deadline.
func NewReceiver(ctx context.Context) *ReceiverAdvisory: Document non-obvious thread safety characteristics.
// Ambiguous operation (looks read-only but mutates internally)
// Lookup returns the data associated with the key from the cache.
//
// This operation is not safe for concurrent use.
func (*Cache) Lookup(key string) (data []byte, ok bool)
// API provides synchronization
// NewFortuneTellerClient returns an *rpc.Client for the FortuneTeller service.
// It is safe for simultaneous use by multiple goroutines.
func NewFortuneTellerClient(cc *rpc.ClientConn) *FortuneTellerClient
// Interface has concurrency requirements
// A Watcher reports the health of some entity (usually a backend service).
//
// Watcher methods are safe for simultaneous use by multiple goroutines.
type Watcher interface {
Watch(changed chan<- bool) (unwatch func())
Health() error
}建议性要求:文档化不明显的线程安全特性。
// Ambiguous operation (looks read-only but mutates internally)
// Lookup returns the data associated with the key from the cache.
//
// This operation is not safe for concurrent use.
func (*Cache) Lookup(key string) (data []byte, ok bool)
// API provides synchronization
// NewFortuneTellerClient returns an *rpc.Client for the FortuneTeller service.
// It is safe for simultaneous use by multiple goroutines.
func NewFortuneTellerClient(cc *rpc.ClientConn) *FortuneTellerClient
// Interface has concurrency requirements
// A Watcher reports the health of some entity (usually a backend service).
//
// Watcher methods are safe for simultaneous use by multiple goroutines.
type Watcher interface {
Watch(changed chan<- bool) (unwatch func())
Health() error
}Advisory: Always document explicit cleanup requirements.
// Good:
// NewTicker returns a new Ticker containing a channel that will send the
// current time on the channel after each tick.
//
// Call Stop to release the Ticker's associated resources when done.
func NewTicker(d Duration) *Ticker
// Good: Show how to clean up
// Get issues a GET to the specified URL.
//
// When err is nil, resp always contains a non-nil resp.Body.
// Caller should close resp.Body when done reading from it.
//
// resp, err := http.Get("http://example.com/")
// if err != nil {
// // handle error
// }
// defer resp.Body.Close()
// body, err := io.ReadAll(resp.Body)
func (c *Client) Get(url string) (resp *Response, err error)建议性要求:必须文档化明确的资源清理要求。
// Good:
// NewTicker returns a new Ticker containing a channel that will send the
// current time on the channel after each tick.
//
// Call Stop to release the Ticker's associated resources when done.
func NewTicker(d Duration) *Ticker
// Good: Show how to clean up
// Get issues a GET to the specified URL.
//
// When err is nil, resp always contains a non-nil resp.Body.
// Caller should close resp.Body when done reading from it.
//
// resp, err := http.Get("http://example.com/")
// if err != nil {
// // handle error
// }
// defer resp.Body.Close()
// body, err := io.ReadAll(resp.Body)
func (c *Client) Get(url string) (resp *Response, err error)Advisory: Document significant error sentinel values and types.
// Good: Document sentinel values
// Read reads up to len(b) bytes from the File and stores them in b.
//
// At end of file, Read returns 0, io.EOF.
func (*File) Read(b []byte) (n int, err error)
// Good: Document error types (include pointer receiver)
// Chdir changes the current working directory to the named directory.
//
// If there is an error, it will be of type *PathError.
func Chdir(dir string) error*PathErrorPathErrorerrors.Iserrors.As建议性要求:文档化重要的错误哨兵值和错误类型。
// Good: Document sentinel values
// Read reads up to len(b) bytes from the File and stores them in b.
//
// At end of file, Read returns 0, io.EOF.
func (*File) Read(b []byte) (n int, err error)
// Good: Document error types (include pointer receiver)
// Chdir changes the current working directory to the named directory.
//
// If there is an error, it will be of type *PathError.
func Chdir(dir string) error*PathErrorPathErrorerrors.Iserrors.AsAdvisory: Provide runnable examples to demonstrate package usage.
*_test.go// Good:
func ExampleConfig_WriteTo() {
cfg := &Config{
Name: "example",
}
if err := cfg.WriteTo(os.Stdout); err != nil {
log.Exitf("Failed to write config: %s", err)
}
// Output:
// {
// "name": "example"
// }
}建议性要求:提供可运行的示例代码,演示包的使用方法。
*_test.go// Good:
func ExampleConfig_WriteTo() {
cfg := &Config{
Name: "example",
}
if err := cfg.WriteTo(os.Stdout); err != nil {
log.Exitf("Failed to write config: %s", err)
}
// Output:
// {
// "name": "example"
// }
}Advisory: Use godoc syntax for well-formatted documentation.
// Good:
// LoadConfig reads a configuration out of the named file.
//
// See some/shortlink for config file format details.// Good:
// Update runs the function in an atomic transaction.
//
// This is typically used with an anonymous TransactionFunc:
//
// if err := db.Update(func(state *State) { state.Foo = bar }); err != nil {
// //...
// }// Good:
// LoadConfig treats the following keys in special ways:
// "import" will make this configuration inherit from the named file.
// "env" if present will be populated with the system environment.// Good:
// Using headings
//
// Headings come with autogenerated anchor tags for easy linking.建议性要求:使用godoc语法,生成格式规范的文档。
// Good:
// LoadConfig reads a configuration out of the named file.
//
// See some/shortlink for config file format details.// Good:
// Update runs the function in an atomic transaction.
//
// This is typically used with an anonymous TransactionFunc:
//
// if err := db.Update(func(state *State) { state.Foo = bar }); err != nil {
// //...
// }// Good:
// LoadConfig treats the following keys in special ways:
// "import" will make this configuration inherit from the named file.
// "env" if present will be populated with the system environment.// Good:
// Using headings
//
// Headings come with autogenerated anchor tags for easy linking.Advisory: Use for documentation when types alone aren't clear enough.
// Good: Multiple params of same type
func (n *Node) Children() (left, right *Node, err error)
// Good: Action-oriented name clarifies usage
// The caller must arrange for the returned cancel function to be called.
func WithTimeout(parent Context, d time.Duration) (ctx Context, cancel func())
// Bad: Type already clear, name adds nothing
func (n *Node) Parent1() (node *Node)
func (n *Node) Parent2() (node *Node, err error)
// Good: Type is sufficient
func (n *Node) Parent1() *Node
func (n *Node) Parent2() (*Node, error)建议性要求:当仅通过类型无法清晰表达时,使用命名返回参数来辅助文档说明。
// Good: Multiple params of same type
func (n *Node) Children() (left, right *Node, err error)
// Good: Action-oriented name clarifies usage
// The caller must arrange for the returned cancel function to be called.
func WithTimeout(parent Context, d time.Duration) (ctx Context, cancel func())
// Bad: Type already clear, name adds nothing
func (n *Node) Parent1() (node *Node)
func (n *Node) Parent2() (node *Node, err error)
// Good: Type is sufficient
func (n *Node) Parent1() *Node
func (n *Node) Parent2() (*Node, error)Advisory: Add comments to highlight unusual or easily-missed patterns.
if err := doSomething(); err != nil { // common
// ...
}
if err := doSomething(); err == nil { // unusual!
// ...
}// Good:
if err := doSomething(); err == nil { // if NO error
// ...
}建议性要求:添加注释来突出不常见或容易被忽略的代码模式。
if err := doSomething(); err != nil { // common
// ...
}
if err := doSomething(); err == nil { // unusual!
// ...
}// Good:
if err := doSomething(); err == nil { // if NO error
// ...
}Advisory: Preview documentation before and during code review.
go install golang.org/x/pkgsite/cmd/pkgsite@latest
pkgsite建议性要求:在代码评审前和评审期间预览文档效果。
go install golang.org/x/pkgsite/cmd/pkgsite@latest
pkgsite| Topic | Key Rule |
|---|---|
| Doc comments | Start with name, use full sentences |
| Line length | ~80 chars, prioritize readability |
| Package comments | One per package, above |
| Parameters | Document non-obvious behavior only |
| Contexts | Document exceptions to implied behavior |
| Concurrency | Document ambiguous thread safety |
| Cleanup | Always document resource release |
| Errors | Document sentinels and types (note pointer) |
| Examples | Use runnable examples in test files |
| Formatting | Blank lines for paragraphs, indent for code |
| 主题 | 核心规则 |
|---|---|
| 文档注释 | 以名称开头,使用完整句子 |
| 行长度 | 约80字符,优先保证可读性 |
| 包注释 | 每个包一个,位于 |
| 参数 | 仅文档化非明显行为 |
| Context | 文档化与隐含行为不符的例外情况 |
| 并发 | 文档化不明确的线程安全特性 |
| 资源清理 | 必须文档化资源释放要求 |
| 错误 | 文档化哨兵值和类型(注意指针) |
| 示例 | 在测试文件中使用可运行示例 |
| 格式 | 使用空行分隔段落,缩进表示代码块 |