.. _go_generate: go generate命令 ############### 格式:: $ go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages] 说明:: -run 正则表达式匹配命令行,仅执行匹配的命令 -v 输出被处理的包名和源文件名 -n 显示不执行命令 -x 显示并执行命令 注释实例:: //go:generate command arg1 arg2 简介 ---- * 官网文档 [3]_ * go generate命令是go 1.4版本里面新添加的一个命令 * 当运行go generate时,它将扫描与当前包相关的源代码文件:: 1. 找出所有包含"//go:generate"的特殊注释,提取并执行该特殊注释后面的命令 2. 命令为可执行程序,形同shell下面执行 有几点需要注意:: 1. 该特殊注释必须在.go源码文件中 2. 每个源码文件可以包含多个generate特殊注释时 3. 显示运行go generate命令时,才会执行特殊注释后面的命令 4. 命令串行执行的,如果出错,就终止后面的执行 5. 特殊注释必须以"//go:generate"开头,双斜线后面没有空格 应用场景:: 1. yacc:从 .y 文件生成 .go 文件 2. protobufs:从 protocol buffer 定义文件(.proto)生成 .pb.go 文件 3. Unicode:从 UnicodeData.txt 生成 Unicode 表 4. HTML:将 HTML 文件嵌入到 go 源码 5. bindata:将形如 JPEG 这样的文件转成 go 代码中的字节数组 其他应用场景:: 1. string方法:为类似枚举常量这样的类型生成String()方法。 2. 宏:为既定的泛型包生成特定的实现,比如用于ints的sort.Ints。 .. warning:: go:generate前面只能使用//注释,且//与go:generate之间不能有空格!!! 使用 ---- 基本:: //go:generate stringer -type ErrCode 选项-type指定stringer命令作用的类型名 在同一个目录下生成一个文件errcode_string.go 文件名格式是类型名小写_string.go 指定输出文件名:: //go:generate stringer -type ErrCode -output code_string.go -linecomment选项:: //go:generate stringer -type ErrCode -linecomment -output code_string.go 实例1 ----- 源码:: package main import "fmt" //go:generate echo hello //go:generate go run main.go //go:generate echo file=$GOFILE pkg=$GOPACKAGE func main() { fmt.Println("main func") } go generate:: $ go generate hello main func file=main.go pkg=main 实例2 ----- 源码:: //go:generate stringer -type=Pill package painkiller type Pill int const ( Placebo Pill = iota Aspirin Ibuprofen Paracetamol Acetaminophen = Paracetamol ) 安装stringer:: $ go get golang.org/x/tools/cmd/stringer or $ git clone https://github.com/golang/tools/ $GOPATH/src/golang.org/x/tools $ go install golang.org/x/tools/cmd/stringer $ go generate:: $ cat pill_string.go // 生成这么一个文件 // Code generated by "stringer -type=Pill"; DO NOT EDIT. package painkiller import "fmt" 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 fmt.Sprintf("Pill(%d)", i) } return _Pill_name[_Pill_index[i]:_Pill_index[i+1]] } 参考 ---- * 参考1 [1]_ * 参数2 [2]_ .. [1] https://www.jianshu.com/p/a866147021da .. [2] https://studygolang.com/articles/22984 .. [3] https://docs.google.com/document/d/1V03LUfjSADDooDMhe-_K59EgpTEm3V8uvQRuNMAEnjg/edit