在编码阶段同步写好类型、变量、函数、包注释,注释可以通过godoc导出生成文档。

程序中每一个被导出的(大写的)名字,都应该有一个文档注释。

所有注释掉的代码在提交 Code Review 前都应该被删除,除非添加注释讲解为什么不删除, 并且标明后续处理建议(如删除计划)。

通用

  • 不要用注释删除代码。
  • 特殊实现需要注释。

风格

  • 注释符 // /* */ 与注释内容之间留一空格。
  • 中英文之间应该留一空格。
  • 注释结束添加结束标点符号,如句号、叹号等,参考标准库源码注释。
  • 如果是英文注释,句子首字母应大写,参考标准库源码注释。

包注释

  • 每个包都应该有一个包注释。
  • 包如果有多个 go 文件,只需要出现在一个 go 文件中(一般是和包同名的文件)即可。
  • 格式为// Package 包名 包信息描述
// Package math provides basic constants and mathematical functions.
package math

// 或者

/*
Package template implements data-driven templates for generating textual
output such as HTML.
....
*/
package template

函数注释

  • 导出的函数和方法(结构体或接口下的函数称为方法)都必须有注释。

注释描述函数或方法功能、调用方等信息。格式为 // 函数名 描述

注意,如果方法的接收器为不可导出类型,可以不注释,但需要质疑该方法可导出的必要性。

// NewtAttrModel 是属性数据层操作类的工厂方法
func NewAttrModel(ctx *common.Context) *AttrModel {
    // TODO
}
  • 避免参数语义不明确。

函数调用中意义不明确的实参可能会损害代码可读性。当参数名称的含义不明显时,请为参数添加 C 样式注释 (/* ... */)

// Bad
// func printInfo(name string, isLocal, done bool)
printInfo("foo", true, true)

// Good 
// func printInfo(name string, isLocal, done bool)
printInfo("foo", true /* isLocal */, true /* done */)

对于上面的示例代码,还有一种更好的处理方式是将上面的 bool 类型换成自定义类型。将来,该参数可以支持不仅仅局限于两个状态(true/false)。

type Region int

const (
  UnknownRegion Region = iota
  Local
)

type Status int

const (
  StatusReady Status= iota + 1
  StatusDone
  // Maybe we will have a StatusInProgress in the future.
)

func printInfo(name string, region Region, status Status)
  • 非导出的函数,如果比较简单,不需要注释。
  • 解析函数应该注明解析字符串的范例,并明确不能处理的异常情况。

结构体注释

  • 每个需要导出的自定义结构体或者接口都必须有注释说明。

注释对结构进行简要介绍,放在结构体定义的前一行。格式为 // 结构体名 描述

  • 必要情况下字段给出注释。

结构体内的可导出成员变量名,如果是个生僻词或意义不明确的词,必须要单独给出注释,放在成员变量的前一行或同一行的末尾。

// User 用户结构定义了用户基础信息。
type User struct {
    Name  string
    Email string
    Demographic string // 族群
}

变量和常量注释

  • 每个需要导出的变量和常量都必须有注释说明。

注释对变量和常量进行简要介绍,放在常量或变量定义的前一行。独行注释格式为:"// 变量名 描述",斜线后面紧跟一个空格。

// FlagConfigFile 配置文件的命令行参数名。
const FlagConfigFile = "--config"

// FullName 返回指定用户名的完整名称。
var FullName = func(username string) string {
    return fmt.Sprintf("fake-%s", username)
}
  • 大块变量或常量定义时的注释方式。

块注释即在代码块前给出一个总的说明,然后每行变量或常量的末尾给出详细注释,这样看起来更加简洁。

// 命令行参数。
const (
    FlagConfigFile1 = "--config" // 配置文件的命令行参数名 1。
    FlagConfigFile2 = "--config" // 配置文件的命令行参数名 2。
    FlagConfigFile3 = "--config" // 配置文件的命令行参数名 3。
    FlagConfigFile4 = "--config" // 配置文件的命令行参数名 4。
)
  • 命名清晰的地方,不要添加无意义的注释。

类型注释

  • 每个需要导出的类型定义(type definition)和类型别名(type aliases)都必须有注释说明。
  • 该注释对类型进行简要介绍,放在定义的前一行。
  • 格式为:"// 类型名 描述"。
// StorageClass 存储类型
type StorageClass string

// FakeTime 标准库时间的类型别名
type FakeTime = time.Time

接口注释

  • 导出与非导出接口均需要有注释。
  • 需要描述谁,在什么场景下,如何使用接口。
powered by Gitbook该文章修订时间: 2024-03-22 15:30:00

results matching ""

    No results matching ""