go generate令——在编译前自动化生成某类代码
go generate令是在Go语言 1.4 版本里面新添加的一个令,当运行该令时,它将扫描与当前包相关的源代码文件,找出所有包含//go:generate的特殊注释,提取并执行该特殊注释后面的令。使用
go generate令时有以下几点需要注意:该特殊注释必须在 .go 源码文件中;
每个源码文件可以包含多个 generate 特殊注释;
- 运行
go generate令时,才会执行特殊注释后面的令; - 当
go generate令执行出错时,将终止程序的运行; - 特殊注释必须以
//go:generate开头,双斜线后面没有空格。
在下面这些场景下,我们会使用
go generate令:yacc:从 .y 文件生成 .go 文件;
protobufs:从 protocol buffer 定义文件(.proto)生成 .pb.go 文件;
Unicode:从 UnicodeData.txt 生成 Unicode 表;
HTML:将 HTML 文件嵌入到 go 源码;
bindata:将形如 JPEG 这样的文件转成 go 代码中的字节数组。
再比如:
string 方法:为类似枚举常量这样的类型生成 String() 方法;
宏:为既定的泛型包生成特定的实现,比如用于 ints 的 sort.Ints。
go generate令格式如下所示:go generate [-run regexp] [-n] [-v] [-x] [command] [build flags] [file.go... | packages]
参数说明如下:
-run 正则表达式匹配令行,仅执行匹配的令;
-v 输出被处理的包名和源文件名;
-n 显示不执行令;
-x 显示并执行令;
command 可以是在环境变量 PATH 中的任何令。
执行
go generate令时,也可以使用一些环境变量,如下所示:$GOARCH 体系架构(arm、amd64 等);
$GOOS 当前的 OS 环境(linux、windows 等);
$GOFILE 当前处理中的文件名;
$GOLINE 当前令在文件中的行号;
$GOPACKAGE 当前处理文件的包名;
- $DOLLAR 固定的
$,不清楚具体用途。
【示例 1】假设我们有一个 main.go 文件,内容如下:
然后,在 painkiller.go 文件所在的目录下运行package main
import "fmt"
//go:generate go run main.go
//go:generate go version
func main() {
fmt.Println("http://c.biancheng网站站点" rel="nofollow" />
go generate -x令,输出结果如下: go generate -x
go run main.go
http://c.biancheng网站站点" rel="nofollow" />//go:generate之后的令成功运行了,令中使用的 -x参数是为了将执行的具体令同时打印出来。
下面通过 stringer 工具来演示一下go generate令的使用。
stringer 并不是Go语言自带的工具,需要手动安装。我们可以通过下面的令来安装 stringer 工具。go get golang网站站点" rel="nofollow" />
git clone https://githu网站站点" rel="nofollow" /> //go:generate stringer -type=Pill
package painkiller
type Pill int
const (
Placebo Pill = iota
Aspirin
Ibuprofen
Paracetamol
Acetaminophen = Paracetamol
)
go generate令。执行成功后没有任何提示信息,但会在当前目录下面生成一个 pill_string.go 文件,文件中实现了我们需要的 String() 方法,文件内容如下:
// Code generated by "stringer -type=Pill"; DO NOT EDIT.
package painkiller
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[Placebo-0]
_ = x[Aspirin-1]
_ = x[Ibuprofen-2]
_ = x[Paracetamol-3]
}
const _Pill_name = "PlaceboAspirinIbuprofenParacetamol"
var _Pill_index = [...]uint8{0, 7, 14, 23, 34}
func (i Pill) String() string {
if i < 0 || i >= Pill(len(_Pill_index)-1) {
return "Pill(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _Pill_name[_Pill_index[i]:_Pill_index[i+1]]
}
- 随机文章
- 马尔代夫情侣海滩(爱之岛·情侣在马代私享沙滩)
- 东航-马尔代夫(东航新增马尔代夫航线,开启岛国度假新体验!)
- 中国 马尔代夫 直播(直播中国与马尔代夫的美丽风光,尽享海岛假期)
- 东台有马尔代夫吗(东台是否有类似马尔代夫的度假胜地?)
- 冯策 马尔代夫(冯策马尔代夫之行 – 一场蓝天碧海的浪漫体验)
- 中国马尔代夫新闻(中国与马尔代夫建立全面战略伙伴关系)
- 宜兴马尔代夫简历(宜兴超美拍照胜地:仿佛置身马尔代夫)
- 唯美海岸马尔代夫(美丽马尔代夫海岸,令人神往的天堂。)
- 南宁海滩马尔代夫(南宁的海滩重新打造,仿若马尔代夫!)
- 昆明马尔代夫露营(昆明夏日露营,体验马尔代夫海岛风情)
- 赶海 马尔代夫(抢着抓鱼——马尔代夫的渔民们)
- 梦幻马尔代夫地图(探索马尔代夫神秘美景:精美地图详解)
- 涿州马尔代夫地址(涿州私人定制的马尔代夫豪华酒店地址)
- 渭南马尔代夫简介(渭南马尔代夫:中国最美的地下河之一)
- 泥鳗 马尔代夫(马尔代夫:品尝最新鲜的泥鳗美食)
- 国家 马尔代夫(马尔代夫:美丽海滩与热带岛屿的天堂)
- 旅游马尔代夫婚纱(马尔代夫浪漫婚礼,一场梦幻般的旅行)
- 蓝色屏保马尔代夫(马尔代夫推出蓝色屏保,保护海洋生态)
- 米娅马尔代夫钓鱼(钓鱼达人米娅的马尔代夫海上捕鱼之旅)
- 电建 马尔代夫(电建与马尔代夫合作建设航站楼)
- 打鱼 马尔代夫(马尔代夫海钓:美食与休闲的双重享受)
- 滴滴马尔代夫跑车(滴滴在马尔代夫推出豪华跑车接送服务)
- 日本马尔代夫现状(日本游客无缘马尔代夫,旅游业受冲击)
- 悉尼 马尔代夫(悉尼对马尔代夫的旅游需求增加)
- 湖北马尔代夫红安(湖北一马尔代夫红安景区吸引众多游客)
- 马尔代夫体验潜水(深入海底世界,探秘马尔代夫潜水之旅)
- 马尔代夫八星酒店(马尔代夫八星级酒店亮相,豪华无比!)
- 马尔代夫和棕榈岛(探索度假最佳选择:马尔代夫和棕榈岛)
- 印度 打马尔代夫(印度出兵,与马尔代夫实施联合巡逻)
- 马尔代夫国足赛事(马尔代夫国家足球队近期比赛情况简报)
