其专业术语为构建约束,其实不止是go文件,也可以运用在其他文件中。一句话总结其作用就是指定文件的编译场景,若满足条件则编译,反之就不会进行编译。
下面进行一个简单的总结,详细内容可以看看官方的设计文档:https://go.googlesource.com/proposal/+/master/design/draft-gobuild.md
什么是构建约束
构建约束(build constraint), 也叫做构建标记(build tag),在源文件中通过注释的方式指定编译环境,若要为不同的编译环境编写不同的go代码,则需要使用构建约束,例如:
1 | // +build linux |
上述的注释行意思是只有在linux环境下才会编译该文件,否则会忽略。
其编写格式需要注意以下几点:
- 可以在任何文件源文件中编写
- 必须在写在文件顶部附近,可以写多行
- 为了区别
package
的文档注释,在约束后必须有空行
其支持类型比较广泛,有以下几种:
指定编译的操作系统:如:windows,linux,darwin(对应runtime.GOOS)
指定架构:如:amd64、386(对应runtime.GOARCH)
指定使用的编译器,如:gccgo、gc
指定go版本,如:go1.17、go1.18
-
老版本语法
在
go1.17
之前是使用的老版本语法,1.17
之后的支持比较完善了。
老版本的构建语法为// +build
这种形式,可以通过空格、逗号或多行进行组合,例如:1
2
3
4// +build linux,386
// 上述构建约束表示的是: linux and 386
// 逗号表示and, 空格表示or比较复杂的写法:
1
2
3// +build linux,386 darwin,!cgo
// 上述构建约束表示的是: (linux and 386) or (darwin and (not cgo))也可以分成多行书写:
1
2
3
4// +build linux darwin
// +build amd64
// 相当于: (linux or darwin) and amd64新版本语法
新版的构建约束使用
//go:
开头:1
//go:build
新版本语法有以下几点需要注意:
//
和go:
之间不能有空格使用的是布尔表达式,而不是逗号和空格等
一个文件只能有一行构建语句,而不是像老版那样支持多行
例如linux and 386
现在这样写:
1 | //go:build linux && 386 |
新的语法主体未Go spec的EBNF标记:
1 | BuildLine = "//go:build" Expr |
也就是说,构建标记的语法与当前形式保持不变,但构建标记的组合现在使用Go的||, &&, !
运算符和括号完成。