//go:build
是 Go 1.17 中引入的新条件编译指令。
它旨在替换// +build
指令,因为新语法带来了一些关键改进:
- 与其他现有的 Go 指令和 pragma 保持一致,例如
//go:generate
- 支持标准布尔表达式,例如
//go:build foo && bar
,而旧// +build
注释的语法不太直观。例如 AND 用逗号表示// +build foo,bar
,OR 用空格表示// +build foo bar
- 它由 支持
go fmt
,它将自动修复指令在源文件中的不正确放置,从而避免常见错误,例如在指令和包语句之间没有留空行。
这两个构建指令将在几个 Go 版本中共存,以确保顺利过渡,如相关提案文档中所述(低于 N = 17,强调我的):
Go 1.N 将开始转换。在 Go 1.N 中:
构建将开始优先//go:build
选择文件行。如果//go:build
文件中没有,则任何// +build
行仍然适用。
如果 Go 文件包含//go:build
不包含// +build
.
//go:build
如果 Go 或程序集文件在文件中包含太晚,则构建将失败。Gofmt 会将错位的 //go:build 和 // +build 行移动到文件中的正确位置。
Gofmt
将使用与其他 Go 布尔表达式(所有和运算符//go:build
周围的空格)相同的规则来格式化表达式。&&
||
如果文件仅包含// +build
行,gofmt
将在它们上方添加等效//go:build
行。
如果文件同时包含//go:build
和// +build
行,gofmt
将考虑//go:build
事实来源并更新// +build
行以匹配,保持与早期版本的 Go 的兼容性。Gofmt
也会拒绝//go:build
被认为太复杂而无法转换为// +build
格式的行,尽管这种情况很少见。(请注意此项目符号开头的“如果”。Gofmt
不会将// +build
行添加到只有 .)的文件中 //go:build
。)
buildtags
签入go vet
将添加对//go:build
约束的支持。当 Go 源文件包含不同含义的行时,它将失败//go:build
// +build
。如果检查失败,可以运行gofmt -w
.
当一个 Go 源文件包含without并且其包含的模块有一个 go 行列出 Go 1.N 之前的版本时,buildtags
检查也会失败。如果检查失败,可以添加任何一行然后运行,它将用正确的行替换它。或者可以将 Go 版本升级到 Go 1.N。//go:build
// +build
// +build
gofmt -w
go.mod
有关语法更改的更多信息:Golang 条件编译