昨天学习了go generate,今天学习另外一个知识点,一样是跟注释有关的知识点。golang的条件编译,也叫编译约束(build constraints)。
应用场景
条件编译可以在适应不同平台操作系统的代码上体现。不同的操作系统平台,对某些特性的支持不太一样,但是往往在业务层面上的代码不会去关注,所以需要对底层的代码进行一些封装。比如,Windows和Linux的home目录是不一样的,而我们的业务需要读取home目录,那此时我们就可以用条件编译来达到效果。
条件编译的两种形式
条件编译可以通过两种方式实现:
- 在源文件开头添加注释;
- 以文件名后缀的方式实现。
以添加注释的方式
注释的格式如下:
// +build tags
tags可以是操作系统,也可以是编译器选项,具体有什么可以填的,请往后面看,我们先看个例子来有个大概的印象:
// +build windows
package main
import "fmt"
func echo() {
fmt.Print("windows")
}
// +build linux
package main
import "fmt"
func echo() {
fmt.Print("linux")
}
package main
func main() {
echo()
}
我写了两个文件,都有echo方法,并在main函数中调用了echo方法,现在运行的话,在Windows环境下会打印“windows”,在Linux环境下会打印“linux”。看到这应该就能大致懂了什么是条件编译以及它的应用场景。
那么我们当我们有多个编译条件呢?比如,Linux下的amd64环境,那应该怎么定义tags?在源文件开头的注释中,可以有多个build的定义,比如:
// +build linux
// +build amd64
也可以这么写
// +build linux,amd64
用逗号分隔表示的是“与”的逻辑,用空格分隔表示“或”的逻辑,看下面的例子:
// +build linux,cgo darwin,cgo
这表示在Linux或苹果的环境下,用cgo编译。
还有一点挺重要的要注意就是在注释之后一定要空一行。如果是想表示只要不在Windows环境下都可以编译,应该这么写:
// +build !windows
如果+build后面的tags是没有定义的,那么编译时会忽略,比如:
// +build abc
现在我们看看有那些tags是我们能填的,从官方文档可以看到以下选项:
- the target operating system, as spelled by runtime.GOOS
- the target architecture, as spelled by runtime.GOARCH
- the compiler being used, either "gc" or "gccgo"
- "cgo", if ctxt.CgoEnabled is true
- "go1.1", from Go version 1.1 onward
- "go1.2", from Go version 1.2 onward
- "go1.3", from Go version 1.3 onward
- "go1.4", from Go version 1.4 onward
- "go1.5", from Go version 1.5 onward
- "go1.6", from Go version 1.6 onward
- "go1.7", from Go version 1.7 onward
- "go1.8", from Go version 1.8 onward
- "go1.9", from Go version 1.9 onward
- "go1.10", from Go version 1.10 onward
- "go1.11", from Go version 1.11 onward
- "go1.12", from Go version 1.12 onward
- "go1.13", from Go version 1.13 onward
- "go1.14", from Go version 1.14 onward
- any additional words listed in ctxt.BuildTags
以文件命名后缀的方式
文件命名的方式比较简单,可以以下面几种形式的命名来条件编译:
*_GOOS //如:file_linux.go,表示只在Linux下编译
*_GOARCH //如:file_amd64.go,表示只在amd64下编译
*_GOOS_GOARCH //如:file_linux_amd64.go,表示只在Linux且amd64下编译
欢迎关注我的公众号:onepunchgo,给我留言。
有疑问加站长微信联系(非本文作者)