go build 构建约束//go:build

123445 · · 1865 次点击 · · 开始浏览    

在看别人源码的时候有时会看到类似这样打头的注释: `//go:build xxxx` 比如gin的`gin/internal/json`包里面就有。 这到底什么意思呢? 这其实是go里面的构建约束,也叫构建标签,build的时候给编译器的标签,可以决定一个文件是否需要包含在包之中。 比如:`//go:build (linux && 386) || (darwin && !cgo)` 表示执行go build的时候,目标系统是386的linux或者没有启用cgo的darwin时,当前文件会被编译进来。 这个就是编译约束。 特性: - 可以出现在任何源文件里面,不仅仅是go源文件。 - 必须写在文件顶部,前面只可以有空白行或其他注释 - 为了区分构建约束和包文件,在构建约束后面应该有一空白行 - 由`||`、`&&`、`!`运算符(或、与、非)和括号组成的表达式 可用的标签: - 目标操作系统,拼写和`runtime.GOOS`一致,可以用命令`go tool dist list`查看可能的值 - 目标系统架构,拼写和`runtime.GOARCH`一致 - `unix`,标识`GOOS`是Unix或者Unix-like系统 - 正在使用的编译器,`gc`或者`gccgo` - `cgo`,如果支持`cgo`命令 - 每个go主要发布版本的术语,比如:`go1.1`,满足从go1.1版本开始,`go1.12`从go1.12版本开始,其他类推 - 通过`-tags`标记给出的其他标签,`-tags`多个标签用逗号分隔列出 `//go:build ignore`:忽略编译 go 1.16和之前的版本的语法是使用`// +build`,gofmt命令在遇到旧语法时会自动添加等效的新语法 gin的`gin/internal/json`就是通过标签来确定使用哪个json库的: ```shell go build -tags=jsoniter go build -tags=go_json ``` 如果一个文件名称,满足如下条件: ```shell *_GOOS *_GOARCH *_GOOS_GOARCH ``` 比如一个文件名称`source_windows_amd64.go`当目标系统是windows系统amd64架构时会包含编译,`GOOS` 和 `GOARCH`分别代表目标系统的类别和架构类型,满足上面规则的文件被认为需要满足这些条件的隐式约束。 例如以下文件名: `dns_windows.go`:编译windows包时才会本文件 `math_386.s`:编译包目标是32-bit x86时包含 这样的好处就是,当同一个方法在不通操作系统下实现是不一样的时候,可以用相同的函数名称分别实现,编译的时候根据目标系统类型编译对应系统的源文件: ```go // test_windows.go package pkg import "log" func PrintOS() { log.Println("windows") } // test_linux.go package pkg import "log" func PrintOS() { log.Println("linux") } //main.go package main import ( "test/pkg" ) func main() { pkg.PrintOS() } ```

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1865 次点击  ∙  1 赞  
加入收藏 微博
1 回复  |  直到 2022-12-06 11:58:34
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传