Go 知识点(18)— 条件编译(编译标签、文件后缀)
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的值,如:linux、darwin、windows等; - 操作系統的架構,環境變量中
GOARCH的值,如:amd64、x86、i386等; - 使用的編譯器,
gc或者gccgo; - 是否開啟
CGO,cgo go版本號:比如Go Version 1.1為go1.1,Go 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)— 条件编译(编译标签、文件后缀)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国内衣行业研究及前
- 下一篇: 2022-2028年中国实心轮胎行业市场