今天遇到了需要使用条件编译的场景,于是查了一下 golang 是如何支持条件编译的。
条件编译简介
go 文档里称之为,Build Constraints,即,编译限制。 也称为 build tag。
//go:build tag_name
其决定了当前文件是否会被当前 package 所包含。
重点:
用于限制一整个文件是否应该被编译入最终的二进制文件,而不是一个文件中的部分代码片段 (block)
build tag 的一些使用场景
- 测试环境使用 mock 服务;而正式环境使用真实数据
- 免费版、专业版和企业版提供不同的功能
- 不同操作系统的兼容性处理。通常用于跨平台,例如 windows,linux,mac 不同兼容处理逻辑。
- go 低版本的兼容处理
低版本兼容场景示例
例如,我之前就看到 gin 框架下有个 any.go 文件,由于 any 是 go 1.18 引入的别名, 所以其对低版本的兼容处理就是通过 build tag 实现的。
// Copyright 2022 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build !go1.18
// +build !go1.18
package gin
type any = interface{}
使用方法
例如 pro.go 在 main.go 的基础上新增了两个收费版功能:
//go:build pro
package main
func init() {
features = append(features,
"Pro 功能 #1",
"Pro 功能 #2",
)
}
编译时,加参数
go build -tags pro
go:build 与 +build 的区别
//go:build
是 Go 1.17 中引入的新条件编译指令格式。它旨在替换
// +build
指令。为何要采用新的格式呢?
对比一下新旧格式的区别就知道了:
//go:build linux && amd64 || darwin
// +build linux,amd64 darwin
显而易见的优势:
- go:build 这种格式,对 coder 来说,更容易理解其逻辑组合
- 与 //go:embed 和 //go:generate 这些命令相比较,格式上进行了统一
实战案例
go build tag 实现开发环境与生产环境采用不同的 embed.FS 策略
参考
- https://github.com/golang/go/issues/44484
- https://www.digitalocean.com/community/tutorials/customizing-go-binaries-with-build-tags
- https://appliedgo.com/blog/what-s-new-in-go-1-17
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式