文章目录
- 聊聊Go语言的注释
-
- 一、注释的格式
-
- [1.1 块注释](#1.1 块注释)
- [1.2 行注释](#1.2 行注释)
- 二、包注释
- 三、命令注释
- 四、类型注释
-
- [4.1 实例注释](#4.1 实例注释)
- [4.2 并发安全注释](#4.2 并发安全注释)
- [4.3 零值注释](#4.3 零值注释)
- [4.4 导出字段注释](#4.4 导出字段注释)
- 五、函数注释
-
- [5.1 参数/返回值/函数作用注释](#5.1 参数/返回值/函数作用注释)
- [5.2 bool返回值函数注释](#5.2 bool返回值函数注释)
- [5.3 形参/返回值名称注释](#5.3 形参/返回值名称注释)
- [5.4 并发安全注释](#5.4 并发安全注释)
- [5.5 特殊例子注释](#5.5 特殊例子注释)
- [5.6 算法功能注释](#5.6 算法功能注释)
- 六、常量/变量注释
-
- [6.1 分组注释](#6.1 分组注释)
- [6.2 组内元素注释](#6.2 组内元素注释)
- [6.3 未分组元素注释](#6.3 未分组元素注释)
- [6.4 类型化元素注释](#6.4 类型化元素注释)
聊聊Go语言的注释
在我们着手编写Go代码的时候,是否有过考虑,该编写什么样的代码注释才会使得代码读起来易懂呢?不会出现我们经常开玩笑说的:"过了几个月,自己写的代码都不认识了"的情况呢?
接下来让我们一起来聊聊Go语言的注释,包括了包注释、命令注释、类型注释、函数注释、变量/常量注释部分,希望能够帮助大家养成良好注释的习惯!
一、注释的格式
在Go语言中支持以下两种注释格式:
1.1 块注释
/**/
是C风格的注释,常用于包的说明文档。同时在表达式中或者禁用大量的代码块非常有用。
go
/*
Package fmt implements formatted I/O with functions analogous
to C's printf and scanf. The format 'verbs' are derived from C's but
are simpler.
.....
*/
package fmt
注:在Go语言包中的doc.go
通常是包的文档性说明。
1.2 行注释
//
是C++风格注释,在Go语言中比较常用。
go
// A fmt is the raw formatter used by Printf etc.
// It prints into a buffer that must be set up separately.
type fmt struct {
buf *buffer
...
}
二、包注释
每个程序包(Package)都应该有一个包注释,该注释介绍了整个Package相关的信息,并且通常设定了对Package的期望效果。
包注释不仅仅可以使用块注释的格式,当然也可以使用行注释的格式,这两种格式在Go语言中都非常常用。
go
// Package path implements utility routines for manipulating slash-separated
// paths.
//
// The path package should only be used for paths separated by forward
// slashes, such as the paths in URLs. This package does not deal with
// Windows paths with drive letters or backslashes; to manipulate
// operating system paths, use the [path/filepath] package.
package path
让我们来解释一下示例中的包注释:
-
包注释的第一句话
// Package path
:这是一个包注释,用于描述接下来的代码文件是一个名为path
的包。这是Go语言约定的一部分,有助于在整个代码库中提供一致的文档。也就是说开头必须声明这个Package,Package后面接着是包的名称。implements utility routines for manipulating slash-separated paths.
:这是对包功能的简要描述。它说明了该包的目的,即实现用于处理斜杠分隔路径的实用程序例程。
-
包注释的其它语句
-
主要是针对包的功能具体使用方法进行一个说明。
-
当然也可以添加包的使用示例(可选)
go/* .... For example, fmt.Sprintf("%[2]d %[1]d\n", 11, 22) will yield "22 11", while fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) equivalent to fmt.Sprintf("%6.2f", 12.0) .... */ package fmt
-
三、命令注释
命令(Command)注释与包注释,但它描述的是程序的行为,而不是程序包中的功能特征。注释的第一句话的开头通常是Command的名称,需要首字母大写(因为是一行的开头)
go
/*
Gofmt formats Go programs.
It uses tabs for indentation and blanks for alignment.
Alignment assumes that an editor is using a fixed-width font.
...
Usage:
gofmt [flags] [path ...]
The flags are:
-d
Do not print reformatted sources to standard output.
If a file's formatting is different than gofmt's, print diffs
to standard output.
-w
Do not print reformatted sources to standard output.
If a file's formatting is different from gofmt's, overwrite it
with gofmt's version. If an error occurred during overwriting,
the original file is restored from an automatic backup.
...
*/
package main
注:命令注释通常使用块注释 来表示,内容主要包括:命令的功能、命令的用法及参数说明等。
四、类型注释
4.1 实例注释
类型(type)注释应该解释type中的每个实例代表了什么。注释的第一句话的开头通常是type的名称或者添加一个A
,需要首字母大写(因为是一行的开头)
go
package zip
// A Reader serves content from a ZIP archive.
type Reader struct {
...
}
4.2 并发安全注释
默认情况下,一个类型被单个goroutine
使用是安全的,如果一个类型支持并发使用的话,那么文档注释应该说明它。
go
package regexp
// Regexp is the representation of a compiled regular expression.
// A Regexp is safe for concurrent use by multiple goroutines,
// except for configuration methods, such as Longest.
type Regexp struct {
...
}
4.3 零值注释
如果一个类型的零值是有意义的,那么也应当进行说明
go
package bytes
// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
...
}
4.4 导出字段注释
对于类型中的每一个具有导出意义的字段(也就是开头首字母是大写)都应该进行说明
go
package io
// A LimitedReader reads from R but limits the amount of
// data returned to just N bytes. Each call to Read
// updates N to reflect the new amount remaining.
// Read returns EOF when N <= 0.
type LimitedReader struct {
R Reader // underlying reader
N int64 // max bytes remaining
}
五、函数注释
5.1 参数/返回值/函数作用注释
函数(func)注释应该解释函数的参数、返回值含义,同时应该解释函数的作用。
go
package strconv
// 例子1:解释了返回值的含义和函数功能
// Quote returns a double-quoted Go string literal representing s.
// The returned string uses Go escape sequences (\t, \n, \xFF, \u0100)
// for control characters and non-printable characters as defined by IsPrint.
func Quote(s string) string {
...
}
// 例子2:解释了参数的含义和函数功能
package os
// Exit causes the current program to exit with the given status code.
// Conventionally, code zero indicates success, non-zero an error.
// The program terminates immediately; deferred functions are not run.
//
// For portability, the status code should be in the range [0, 125].
func Exit(code int) {
...
}
5.2 bool返回值函数注释
对于bool
返回值的函数,通常使用reports whether
来描述函数功能,而不是使用or not
go
package strings
// HasPrefix reports whether the string s begins with prefix.
func HasPrefix(s, prefix string) bool
5.3 形参/返回值名称注释
函数的形参的命名和返回值的命名必须要见名知意,并且可以将它们添加到文档注释中,使得文档注释更容易理解。
go
package io
// Copy copies from src to dst until either EOF is reached
// on src or an error occurs. It returns the total number of bytes
// written and the first error encountered while copying, if any.
//
// A successful Copy returns err == nil, not err == EOF.
// Because Copy is defined to read from src until EOF, it does
// not treat an EOF from Read as an error to be reported.
func Copy(dst Writer, src Reader) (n int64, err error) {
...
}
5.4 并发安全注释
同样的,和类型注释一样,若函数是并发安全的,那么也需要在函数注释中说明。
go
package sql
// Close returns the connection to the connection pool.
// All operations after a Close will return with ErrConnDone.
// Close is safe to call concurrently with other operations and will
// block until all other operations finish. It may be useful to first
// cancel any used context and then call Close directly after.
func (c *Conn) Close() error {
...
}
5.5 特殊例子注释
当然,如果函数特殊例子,那么函数注释也应当说明:
go
package math
// Sqrt returns the square root of x.
//
// Special cases are:
//
// Sqrt(+Inf) = +Inf
// Sqrt(±0) = ±0
// Sqrt(x < 0) = NaN
// Sqrt(NaN) = NaN
func Sqrt(x float64) float64 {
...
}
5.6 算法功能注释
函数注释不应解释内部细节,例如当前实现中使用的算法。这些最好留给函数体内部的注释。这样做的好处是: 将来可以更加容易的将该函数更改为不同的算法,而不需要改动文档。
go
package sort
// Sort sorts data in ascending order as determined by the Less method.
// It makes one call to data.Len to determine n and O(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
...
}
六、常量/变量注释
6.1 分组注释
可以对常量(const
)/变量(variable
)进行分组表示,同时一般使用单行注释来说明。
go
package scanner // import "text/scanner"
// The result of Scan is one of these tokens or a Unicode character.
const (
EOF = -(iota + 1)
Ident
Int
Float
Char
...
)
6.2 组内元素注释
有时候,常量/变量里面的每一个元素都需要记录其作用
go
package unicode // import "unicode"
const (
MaxRune = '\U0010FFFF' // maximum valid Unicode code point.
ReplacementChar = '\uFFFD' // represents invalid code points.
MaxASCII = '\u007F' // maximum ASCII value.
MaxLatin1 = '\u00FF' // maximum Latin-1 value.
)
6.3 未分组元素注释
另一方面,未分组的常量/变量的注释开头通常为名称。例如:
go
package unicode
// Version is the Unicode edition from which the tables are derived.
const Version = "13.0.0
6.4 类型化元素注释
类型化常量/变量显示在其类型的声明旁边,因此通常会省略常量/变量注释,而使用该类型的文档注释。
go
package syntax
// An Op is a single regular expression operator.
type Op uint8
const (
OpNoMatch Op = 1 + iota // matches no strings
OpEmptyMatch // matches empty string
OpLiteral // matches Runes sequence
OpCharClass // matches Runes interpreted as range pair list
OpAnyCharNotNL // matches any character except newline
...
)
好啦,本文到此就结束喽!介绍了五种类型的注释方法,希望能对您编写良好的Go语言注释有所帮助。若文章中出现任何纰漏,欢迎大家指正批评哦!如果觉得写得还不错的话,麻烦大家点赞收藏加关注哦!