goland代码规范之代码注释

我们为了保证整个项目的一致性、可读性,对注释规范做了更加严格和详细的修改。

PR评审时务必注意代码注释问题。

注释的意义

  • 注释可以帮助我们很好地完成文档的工作,写得好的注释可以方便我们以后的维护,也方便新人们更好更快地入手项目。
  • 好的注释应该简洁明了, 适当注释,仔细衡量,不要隐晦也不要多余。
  • “优秀的代码应该是自解释的,好代码本身就是注释”,如果无法做到,请加注释。

整体注释要求

(1)注释必须只能使用英文进行注释,对于字符之间应当严格使用空格分隔。

(2)除了包注释外注释使用 /**/ 多行注释外,其他注释风格应当使用单行注释 // 。

样例:

Bad:

/**
...
**/
func listUser() error{
    
    
    ...
}

Good:

// listUser lists all users of department
func listUser() error{
    
    
    ...
}

(3)单行注释不要过长,应保持和代码风格一致,不应超过120个字符;超过的请使用换行展示,尽量保持格式优雅,便于阅读

(4)单行注释中的注释标记符和注释内容应以单个空格隔开

样例

Good:

// listUser lists all users of department
func listUser() error{
    
    
    ...
}

Bad:

//listUser lists all users of department
func listUser() error{
    
    
    ...
}

(5)所有注释都应当使用第三人称单数。

样例:

Bad:

// listUser list all users of department
func listUser() error{
    
    
    ...
}

(6)在代码中,请避免每行代码都注释,应控制注释的数量,提高注释的质量

注释风格严格遵循以上要求。

文件注释

  • 每个文件都应该有一个文件注释,处于文件的最开头
  • 一个文件注释至少包含以下基本信息,(是否应当包含文件描述信息Description)
/*
 * Author:       xiexiaoyu
 *
 * START DATE:   2023/2/25 14:28
 *
 * CONTACT:     [email protected]
 */

文件注释应当通过代码注释模板自动注释,在Goland的注释模板应当为:

/*
 * Author:       xiexiaoyu
 *
 * START DATE:   ${DATE} ${TIME}
 *
 * CONTACT:      [email protected]
 */


package ${
    
    GO_PACKAGE_NAME}

结构(接口)注释

(1)每个自定义的结构体或者接口都应该有注释说明,该注释对结构进行简要介绍,放在结构体定义的前一行,格式为: 结构体名, 结构体说明

(2)如果结构体属性较多,则结构体内的每个成员变量添加注释

// User defines user info
type User struct {
    
    
    // user name
    Username  string 
    // email
    Email     string
}

在一些结构体中,一些简单的约定俗成的字段可不进行注释,比如:

Name
Email
......

但应当注意,当一个结构体出现一些易于混淆的字段时,即使字段再简单也应当对其进行注释用以区分。

样例:

Good:

type PermissionModel struct {
    
    
	UGID   string
	Path   string
	Method string
	// english name
	Nickname string
	Pid      string
}

Bad:

像下面这个示例,所有字段都没注释,而且很多字段都是该模块中专有的名词,阅读代码的人一脸懵逼

type yciRepo struct {
    
    
	db            *Data
	cron          *gron.Cron
	vmCache       *go_cache.Cache
	sc            string
	snapshotClass string
	mlockImg      string
	consul        string
	remoteProm    string
	vmWhiteLIst   []string
	log           *log.Helper
	operator      map[string]func(yciID string) error
}

(3)如果为接口,则以以下方式描述:

// FileInfo is the interface that describes a file and is returned by Stat and Lstat.
type FileInfo interface {
    
    }

样例:

Good

Bad:

没注释

type UserRepo interface {
    
    
	SSOLogin(ctx context.Context, ticket string) (*Token, error)
	GetWxUserInfo(ctx context.Context, uid string) (*WxUserInfo, error)
	GetUserInfo(ctx context.Context, uid string) (*Member, error)
	ListRandomUsers(ctx context.Context, num int32) ([]*MemberMeta, error)
	ListRecommendUsers(ctx context.Context, num int32) ([]*MemberMeta, error)
	UpdateUserTags(ctx context.Context, uid string, tags []string) error
	UpdateUserAvatarUrl(ctx context.Context, uid, avatarUrl string) error
}

函数(方法)注释

(1)每个函数,或者方法(结构体或者接口下的函数称为方法)都应该有注释说明

(2)函数注释不区分大写函数还是小写函数,特别是一些比较复杂的函数,必须注释

样例

Bad

func (u *userRepo) syncUsers() {
    
    
    ...
}

函数注释不区分大小写函数,应该对函数做一个详细的描述,特别简单的除外。

Good

// syncUsers ...
// step1: ...
// step2: ...
// step3: ...
func (u *userRepo) syncUsers() {
    
    
    ...
}

(3)注释的首个单词应该和函数名保持一致

// Dial connects to the address on the named network.
func Dial(network, address string) (Conn, error) {
    
    
    ...
}

(4)如果在函数或者方法注释中例子能更好地阐明函数使用以及意图,请添加适当的例子

// Dial connects to the address on the named network.
//
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
// "unixpacket".
//
// Examples:
//    Dial("tcp", "golang.org:http")
//    Dial("tcp", "192.0.2.1:http")
//    Dial("tcp", "198.51.100.1:80")
//    Dial("udp", "[2001:db8::1]:domain")
//    Dial("udp", "[fe80::1%lo0]:53")
//    Dial("tcp", ":80")
func Dial(network, address string) (Conn, error) {
    
    
    
}

代码块注释

  • 每个代码块代表一个代码逻辑,应该添加单行注释
// 代码块的执行逻辑
if result > 0 {
    
    
    
}
  • error处理一般不带注释
if err != nil {
    
    
    
}

变量、全局常量注释

  • 每个常量( const )、全局变量( var )都应该写明注释
  • 注释的首个单词应该和变量名、常量名保持一致
const (
    // ID is the identifier of container
    ID = "id"
)

其他说明

(1)当某个部分等待完成时,可用 TODO(name): 开头的注释来提醒开发人员。

func GetComment(ctx context.Context, objId string) ([]*biz.CommentMeta, error) {
    
    
    // TODO(xiexiaoyu): add limit and offset
    ...
}

(2)当某个部分存在已知问题进行需要修复或改进时,可用 FIXME: 开头的注释来提醒开发人员。

func DeleteComment(ctx context.Context, uid, objId string, id int) error {
    
    
    // FIXME(xiexiaoyu): delete comment
    ...
}

(3)当需要特别说明某个问题时,可用 NOTE: 开头的注释:

// NOTE: os.Chmod and os.Chtimes don't recognize symbolic link,
// which will lead "no such file or directory" error.
return os.Symlink(target, dest)

猜你喜欢

转载自blog.csdn.net/qq_26356861/article/details/131289320