跳转到主要内容
模块 9 · 第 5 课(共 5)课程中的45/50~10 min
模块课程(5/5)

构建约束和标签

构建约束(也称为构建标签)根据操作系统、架构、Go 版本或命令行上传递的自定义标签来控制文件的编译。它们用于跨平台代码、选择加入大量测试文件和类似场景。

现代语法://go:build

从 Go 1.17+ 开始,规范格式是特殊的 //go:build 注释,放置在文件顶部 package 之前,单独占一行,后跟一个空行:

Go
//go:build linux

package main

// this file is built ONLY on Linux

三个绝对规则:

  1. 注释必须出现在 package 之前。
  2. 后面必须有空行。
  3. // 和 go:build 之间没有空格(这是一个语法触发器,而不仅仅是任何注释)。

布尔表达式

//go:build 之后的表达式接受逻辑运算符:

Go
//go:build linux && amd64           // both conditions
//go:build linux || darwin          // any one (Unix-like)
//go:build !windows                 // negation
//go:build (linux || darwin) && !arm64
//go:build go1.22                   // Go version ≥ 1.22
//go:build integration              // custom tag (see below)

最常见的内置标签:

  • 操作系统:linux、darwin、windows、freebsd、js...
  • 架构:amd64、arm64、386、wasm...
  • Go 版本:go1.20、go1.22...(如果版本 ≥,则为 true)。
  • cgo:如果启用了 cgo,则为 true。

跨平台:文件名约定

除了显式标签之外,Go 还将 文件名后缀 识别为隐式构建约束:

Code
db_linux.go         // linux only
db_windows.go       // windows only
db_linux_amd64.go   // linux/amd64 only

这是同一接口的平台相关实现的惯用模式(每个文件用不同的代码定义相同的函数)。

自定义标签:选择进行繁重的测试

自定义标签是您在命令行上传递的任何标识符:

Go
//go:build integration

package mypkg

// tests that need a real DB, run only on demand

执行:

Bash
go test -tags=integration ./...

如果没有 -tags=integration,该文件对编译器来说是不可见的(对于 go test 来说,其中的测试不存在)。这是将单元测试(始终)与集成测试(按需,可能仅在 CI 中)分开的规范方法。

旧语法:// +build(已弃用)

在 1.17 之前,格式为 // +build linux (注意空格,它是 +build,而不是 go:build)。它仍然支持向后兼容,但 Go 1.17+ 中的 gofmt 在只找到旧的时添加了 both :

Go
//go:build linux
// +build linux

package main

对于新文件,仅使用现代的 //go:build 形式。

练习

锻炼#go.m9.l5.e1
尝试:0加载中...

在文件顶部添加仅在 Linux 上编译的构建约束。记住打包前的空行。

正在加载编辑器...
显示提示

//go:build 注释位于 package 之前,单独占一行,后跟一个空行。

3 次尝试后可用的解决方案

锻炼#go.m9.l5.e2
尝试:0加载中...

添加排除 Windows 的构建约束(使用否定运算符!)。

正在加载编辑器...

3 次尝试后可用的解决方案

Quiz#go.m9.l5.e3
准备好

要在测试时启用使用 //go:build 集成声明的自定义“集成”标签,您使用哪个标志?

Go
$ go test -tags=???
答案选项