Golang条件编译

时间:2024-10-13 08:04:12

条件编译

简介

      条件编译指的是只编译满足条件的代码段。
      很多情况下我们的程序需要根据不同阶段、不同的使用场景做对应的设置或约束,代码中如果写了太多的判断逻辑会显得非常冗余,且可读性、可维护性也比较差,程序体积也会增加。若采用条件编译,只编译满足条件的代码段,则可以有效地避免到处写相同的判断逻辑程序体积也能够显著减小(打个比方:if…else if…else 这3个分支的逻辑仅编译满足条件的分支逻辑)。
      举个例子
      某系统设计了两种模式,一种是普通模式,另一种是安全模式,系统同时只能使用一种模式。普通模式密码直接用md5,而安全模式密码用aes加密算法。这时候如果在代码里面判断当前模式再做对应的处理,可以实现目的,但不够优雅,若后续很多地方依赖于密码操作,则到处都需要先判断模式再做密码处理,写了不少冗余代码不说,还降低了可读性和可维护性(后续如有更多模式,还得到处修改),项目体积也增大了。
      如果基于条件编译来构建代码,则根本不用到处写判断,只需要根据不同模式划分文件,不同模式外层调用逻辑相同但底层的逻辑不同,对于调用层而言调用的是相同的常量、变量、函数,但是由于条件编译的关系在编译期已经根据条件编译了对应的代码,此时调用层就能够根据需要去调用并执行对应的逻辑。就解决了上述到处写判断逻辑的各种问题。

说明

Golang中通过在.go文件声明包名之前定义如下注释:
//+build tagI,tagII tagIII,tagIV ...

1、上述注释具有标签的意义,编译时根据指定标签编译对应的文件;
2、该注释要求与上下内容至少空一行,避免被当成纯注释信息而无法参与条件编译;
3、标签之间的逻辑意义:
3.1、逗号[,]或换行(另起一行写/ /+build)表示And,即 &&3.2、空格[ ]表示Or,即 ||3.3、感叹号[!]表示Not,即 !;
ex:
//+build aa,bb cc,dd
逻辑意义(aa And bb) Or (cc And dd)
//+build aa bb
//+build cc
逻辑意义(aa Or bb) And cc
//+build aa,!bb
逻辑意义 aa And (Not bb)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

示例

在这里插入图片描述
正常情况下代码中同一个包内不允许重复定义常量、变量、函数,否则会报重定义的错误,但由于条件编译的关系,这两个文件同时只能满足一个匹配条件,也就是说同时只能有一个参与编译,因此不会产生冲突。

使用命令:go build -tags develop xxx 即可编译含有develop标签的文件,而标签不满足的则不参与编译,无设置标签的均作为公共文件默认参与编译;

结果

使用develop为tag:
在这里插入图片描述
使用product为tag:
在这里插入图片描述
由此可见,同一个包中即便有若干文件中定义了同名全局常量、变量、函数等,只要能够满足编译条件,就能够根据条件编译目标代码段。条件编译在不同阶段、不同场景下的作用还是非常凸显的。

编辑器(此处只介绍Goland)

若文件加上了标签的注释,则Goland也会有一定的适配。
在这里插入图片描述
如上图,若标签不匹配则会出现上述提示信息,只要如下图设置标签即可识别。
在这里插入图片描述
Tip:此处要提一下,设置标签的时候windows、linux等平台,amd64、386等CPU架构都是有意义的,编译时与GOOS和GOARCH相关,作用与文件名携带后缀 _windows_amd64.go 或 _linux_amd64.go 一致,可参考:Golang交叉编译