1. 条件编译

Go 能根据所处环境选择对应的源码进行编译。让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就叫做条件编译。

Go 中,也称之为 Build Constraints 编译约束,添加编译约束的以下 2 种:

  • 编译标签(build tag
  • 文件后缀

2. 编译标签

​编译标签是一种通过在源码文件顶部添加注释,来决定文件是否参与编译的约束方式。其格式如下:

// +build <tags>

注意:// +build 的下一行必须是空行,否则会被解析为包注释。

// +build linux// main package comment
package main

Go 语言在构建一个包的时候会读取这个包里的每个源文件并且分析编译标签,这些标签决定了这个源文件是否参与本次编译。

tags 说明:

  • 以空格分开表示 OR
  • 以逗号分开表示 AND
  • ! 表示 NOT
  • 一个文件可以有多个 +build 构建标记,它们之间的关系是逻辑 的关系

标签可以指定为以下内容:

  • 操作系统,环境变量中 GOOS 的值,如:linuxdarwinwindows等;
  • 操作系统的架构,环境变量中 GOARCH的值,如:amd64x86i386 等;
  • 使用的编译器,gc 或者 gccgo
  • 是否开启 CGOcgo
  • go版本号:比如 Go Version 1.1go1.1Go Version 1.12 版本为 go1.12 以此类推。

其它自定义标签,通过 go build -tags 指定的值。

使用示例:

  • 编译条件为 (linux AND 386) OR (darwin AND (NOT cgo))
// +build linux,386 darwin,!cgo
  • 多个编译约束,比如条件为 (linux OR darwin) AND amd64
// +build linux darwin// +build amd64
  • 也可以使用 ignore 标签将一个文件从编译中排除。
// +build ignore
  • linux 或者 windows amd64
// +build linux windows,amd64package main

多个 +build 构建标记一般分成每行一个 +build 构建标记。

Gin 框架中,也较多地使用了编译标签,例如 internal/json 目录,这个目录目前只有 json 包。在 json 包中,这个包的两个文件分别都使用了标签 jsoniter

jsoniter.go 内容

// Copyright 2017 Bo-Yi Wu.  All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.// +build jsoniterpackage jsonimport "github.com/json-iterator/go"var (json = jsoniter.ConfigCompatibleWithStandardLibrary// 通过函数值,Marshal 等函数都由 Gin 下的 json 包导出Marshal = json.MarshalUnmarshal = json.UnmarshalMarshalIndent = json.MarshalIndentNewDecoder = json.NewDecoderNewEncoder = json.NewEncoder
)

json.go 内容

// Copyright 2017 Bo-Yi Wu.  All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.// +build !jsoniterpackage jsonimport "encoding/json"var (// 通过函数值,Marshal 等函数都由 Gin 下的 json 包导出Marshal = json.MarshalUnmarshal = json.UnmarshalMarshalIndent = json.MarshalIndentNewDecoder = json.NewDecoderNewEncoder = json.NewEncoder
)

Gin使用 encoding/json作为默认的 json包,但可以通过从其他标签构建来改变它。

  • jsoniter
$ go build -tags=jsoniter .

上述命令表示使用 jsoniter.go 文件来编译生成可执行文件。

  • go_json
$ go build -tags=go_json .

Gin 框架编译时,可以通过编译标签自由选择性编译。编译时如果指定 -tags=jsoniter,则会选择 jsoniter.go 进行编译,默认情况下一般都没有指定这个标签,所以使用的是标准库的 json 包。

由于第三方包 jsoniter 性能上要优于标准库的 json 包,而且这个包提供 100% 与标准库 json 包兼容选项,加上主要函数签名一致,所以 Gin 这里特意封装了新的 json 包,通过编译标签,程序编译时很容易根据实际标签来选择具体实现的代码包。

3. 文件后缀

除了编译标签,第二种添加编译约束的方法是通过源码文件的文件名实现的,这种方案比构造标签方案更简单。编译器也会根据文件后缀来自动选择编译文件:

$filename_$GOOS.go
$filename_$GOARCH.go
$filename_$GOOS_$GOARCH.go
  • $filename: 源文件名称;
  • $GOOS: 表示操作系统,从环境变量中获取;
  • $GOARCH: 表示系统架构,从环境变量中获取;

后缀的顺序记住不要颠倒,后缀中同时出现系统和架构名时,需要保持$filename_$GOOS_$GOARCH.go 的顺序。

标准库 os 源代码的部分截图:

构建标签和文件名后缀在功能上是重叠的,根据需要选择合适的就行。

参考:
https://mp.weixin.qq.com/s?__biz=MzAxNzY0NDE3NA==&mid=2247489316&idx=2&sn=5b556235a63781c852e490da67823f7d&chksm=9be338c5ac94b1d376f94b3d8990ec8062cae9745f1d1e0314b116d6003b48e8bbd72701b249&scene=126&&sessionid=1642228531#rd

Go 知识点(18)— 条件编译(编译标签、文件后缀)相关推荐

  1. Linux下的文件类型、文件后缀名 知识点解析

    文章目录 1.Linux文件的扩展名: 2.Linux 文件类型: 参考博客: https://blog.csdn.net/AQRSXIAO/article/details/82774729 人需要不 ...

  2. c语言是以文件为单位编译,c语言从头开始(三:编译器工作原理) (我们还可以自己编写头文件后缀是xx.h并把它当前代码文件所在目录我们要用就可以直接通过下面代码使用)...

    c语言从头开始(三:编译器工作原理) [[枫歌枫歌]c语言从头开始(三:编译器工作原理)]https://toutiao.com/group/6568056688174170628/?iid=1590 ...

  3. linux编译静态库的头文件,条件编译,头文件,静态库,共享库与多文件编程

    条件编译 条件编译即满足某些条件的时候编译某部分代码,常用于开发多个版本的程序,当满足条件A时,编译出免费版本的软件,当满足条件B时,编译除vip版本的软件,可以提高代码的复用率.条件编译使用&quo ...

  4. 文件后缀名(项目与编译环境经验记录1)

    1.C语言编译成功后生成后缀名为.o文件 (1)是编译成功后的文件,以hello.c为例: 先将源文件编译成目标zhi文件: gcc - c hello.c 这样就生成hello.o文件,再将目标文件 ...

  5. Linux下的文件及文件后缀名

    1.Linux文件的扩展名: 一谈到文件类型,大家就能想到Windows的文件类型,比如file.txt.file.doc.file.sys.file.mp3.file.exe等,根据文件的后缀就能判 ...

  6. 转--各种文件后缀名与打开方式大全

    各种文件后缀名与打开方式大全 .aiff 声音文件 Windows media Player .!!! Netants 暂存文件 Netants .ani 动画鼠标 .arj 压缩文件 ARJ .av ...

  7. 文件后缀名大全及其说明表

    文件后缀名大全及其说明表 转自:http://wf66.com/bbs/200410/35382.htm A 对象代码库文件 AAM Authorware shocked文件 AAS Authorwa ...

  8. python编程的文件后缀是什么意思_python文件的后缀名是什么

    python文件的后缀名有:".py".".py3".".pyc".".pyo".".pyd".&q ...

  9. 各种文件后缀名与打开方式大全a-d

    各种文件后缀名与打开方式大全a-d 2012年01月11日 [b]扩展名 文件类型 打开方式[/b][b] .aiff 声音文件[/b][b] Windows media Player .!!! Ne ...

最新文章

  1. Vue教程6【完结】【vue-router】路由,路由传参,编程式路由导航,缓存路由组件,路由守卫,路由模式,vue ui组件库
  2. 谈谈读“SEO实战密码”的一些感悟
  3. C_Imap 邮件的imap
  4. Golang的模板与渲染
  5. linux下交叉编译libusb的方法及编译一个使用了libusb库的test程序的方法
  6. 修改centos7容器的时间和宿主机时间一致
  7. Apache Kafka 不需要管理员:删除 Apache ZooKeeper 的依赖
  8. 【仿59store校园o2o系统 v6.8】夜猫店+校园超市+学生街+微信公众号绑定+校园跑腿插件
  9. 计算机专业外语英译汉,信科计算机专业英语英译汉
  10. E/Trace: error opening trace file: No such file or directory
  11. 官方华为鸿蒙os正式推送的版本,鸿蒙OS 2.0他来了!华为HarmonyOS 2.0开发者公测版正式推送...
  12. [51单片机] 四相五线减速比为1/64步进电机驱动设计
  13. 电脑上装WPS好还是office好【图解】
  14. 苹果手机自带表格软件_苹果手机还自带扫描仪,没想到今天才发现
  15. 计算机求百钱买百鸡问题采用,5.5 百钱买百鸡问题
  16. iphone自动下载当天VOA
  17. 萌翻全场!硕士爸爸怀抱1岁萌娃参加毕业典礼:带他提前20年体验毕业
  18. 智能家居-电热水器工作原理(转载)
  19. 1046: 数值统计
  20. 施工企业安全教育培训数字化解决方案

热门文章

  1. RabbitMQ 入门系列(11)— RabbitMQ 常用的工作模式(simple模式、work模式、publish/subscribe模式、routing模式、topic模式)
  2. python中的新式类与旧式类的一些基于descriptor的概念(上)
  3. debian10 简单搭建squid
  4. 【JavaScript总结】JavaScript发展与学习内容
  5. 自然语言处理深度学习篇-BiLSTM文本挖掘实践 命名实体识别
  6. torch.nn.Linear()函数的理解
  7. 机器翻译注意力机制及其PyTorch实现
  8. Imagination 的神经网络加速器和 Visidon 的去噪算法被证明是完美的搭档
  9. Compiler编译过程
  10. OFRecord 数据集加载