Go Wiki: 注释

Go 支持 C 风格的 /* */ 块注释和 C++ 风格的 // 行注释。行注释是常用方式。

文档注释

包和导出的名称应该有文档注释。文档注释遵循特定的约定并支持简单的格式化语法。更多信息请参阅 Go 文档注释

指令

某些工具,包括 go 工具编译器支持出现在注释中的指令。除了少数为了兼容性而存在的例外情况外,这些注释指令都是以 //go: 开头的行注释,并且在 //go: 之间没有空格。

go 工具指令

//go:build

go 工具支持构建约束。这些是 //go:build 指令,描述了文件应该包含在包中的条件。

约束的示例用法如下:

约束也可以是表达式

约束可以设置编译文件时使用的语言版本。例如,约束 //go:build go1.23 只会在使用 Go 1.23 或更高版本时编译文件,并且在构建文件时会使用 Go 1.23 的语言语义。如果 go.mod 是较早的版本,这会很方便。例如,这允许定义提供 Go 1.23 函数迭代器的函数,但仅在使用 Go 1.23 或更高版本构建时才有效。

在 Go 1.16 及更早版本中,构建约束是使用以 // +build 开头的注释编写的,并且不允许使用通用表达式。gofmt 程序会将旧的 // +build 语法重写为新的 //go:build 语法。

//go:generate

go generate 命令查找 //go:generate 指令以找到要运行的命令。

此指令的一个示例是 //go:generate stringer -type=Enum,用于运行 stringer 工具,为整数类型的值定义 String 方法。

//go:embed

embed 包使用 //go:embed 指令将源文件嵌入到生成的二进制文件中。单个文件可以嵌入为 string[]byte。一组文件可以嵌入为 embed.FS,它实现了 fs.FS 接口

例如,可以使用以下指令将名为 templates 的子目录内容嵌入到程序中:

//go:embed templates
var templatesSource embed.FS

// tmpls holds the parsed embedded templates.
// This does not read files at run time,
// it parses the data embedded in the binary.
var tmpls = template.ParseFS(templatesSource)

编译器指令

Go 编译器支持多种指令

//line

//line 指令允许设置后续代码使用的文件名、行号和列号。出于历史原因,此指令不以 //go: 开头。当 Go 文件是从其他源生成时,这很有用,它可以使错误消息或堆栈跟踪引用那个其他源文件,而不是生成的源文件。

在行内,可以使用 /*line 块注释,这对于设置列位置很有帮助。

//line foo.src:10
var x = /*line foo.src:20:5*/ 3

//go:noescape

//go:noescape 指令后面必须跟一个没有函数体的函数声明,表明该函数未在 Go 中实现。该指令告诉编译器,传递给函数的指针不会逃逸到堆上,也不会由函数返回。

其他编译器指令

还有许多其他编译器指令用于特殊目的。详细信息请参阅编译器文档

未文档化的编译器指令

编译器还支持一些未文档化的指令。通常这些不应该在用户代码中使用。其中一些仅在编译 runtime 包时可用。

cgo 注释

cgo 工具使用紧跟在 import "C" 语句之前的一系列注释。这一系列注释称为 cgo 前导区 (preamble),它们定义了 Go 代码可以使用特殊的 C 包引用的名称。

package main

// #include <stdio.h>
import "C"

func main() {
    C.puts(C.CString("hello world"))
}

在前导区内,cgo 识别以 #cgo 开头的指令。这些指令可用于设置要使用的 C 编译器和链接器标志,或描述某些 C 函数的行为。详细信息请参阅cgo 文档

cgo export

在使用 cgo 的文件中,可以使用 //export 指令使 Go 函数对 C 代码可见。语法是在 Go 函数 GoName 之前的注释中写入 //export CName。这将安排使得 C 调用函数 CName 实际上会调用 Go 函数 GoName。详细信息请参阅cgo 文档

cgo 编译器指令

cgo 工具生成 Go 代码,生成的代码使用一些特殊指令,这些指令主要只在 cgo 生成的代码中可用。除了 cgo 源代码中,这些指令大多没有文档记录。


此内容是 Go Wiki 的一部分。