转载地址:https://blog.csdn.net/weixin_44264674/article/details/107780595
最近公司需要将状态码快速转成语言包,又想在makefile执行是一次性执行。随即用到了go generate并记录。
介绍
go generate命令是go 1.4版本里面新添加的一个命令,当运行go generate时,它将扫描与当前包相关的源代码文件,找出所有包含"//go:generate"的特殊注释,提取并执行该特殊注释后面的命令,命令为可执行程序,形同shell下面执行。
使用场景
在有些场景下,我们会使用go generate:
在build之前生成一些特定文件(下文介绍)
yacc:从 .y 文件生成 .go 文件.
protobufs:从 protocol buffer 定义文件(.proto)生成 .pb.go 文件。
Unicode:从 UnicodeData.txt 生成 Unicode 表.
注意事项
必须在.go源码文件中
每个源码文件可以包含多个generate特殊注释时
显示运行go generate命令时,才会执行特殊注释后面的命令
如果前面的注释执行出错,则种植执行
使用
环境变量
在使用go generate时,有一些环境变量可以使用:
$GOARCH
体系架构 (arm、amd64等)
$GOOS
OS环境(linux、windows等)
$GOFILE
当前处理中的文件名
$GOLINE
当前命令在文件中的行号
$GOPACKAGE
当前处理文件的包名
$DOLLAR
美元符号
执行方法
假设有一个main.go文件,内容如下:
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("Hello world!")
}
命令行执行 go gennerate之后,输出如下:
$ go generate
hello
Hello world!
file=main.go pkg=main
实例
将 code.go 中状态码对应的 const 注释转换成 .yaml 格式文件。
ps :不知道官方有没有转换的包,用笨办法写了一个脚本文件。
文件结构
如图:
changeToolForCode :用go写的脚本文件
code.go:定义状态码
language_pkg.yaml:存放状态码对应的翻译内容
代码内容
code.go文件:
package test
//go:generate changeToolForCode "./code.go" "./language_pkg.yaml" resp
const (
FAILED Code = -1 // 失败
SUCCESS Code = 0 // 成功
ReqArgsErr Code = 100400 // 请求参数错误信息
SaveRecordFailed Code = 100500 // 后台存储记录失败
)
changeToolForCode 脚本内容:
#!/usr/bin/env gosl
import "fmt"
import "strings"
import "bufio"
import "io/ioutil"
import "os"
if len(os.Args) != 4 {
fmt.Println("请检查输入的读取文件写入文件路径,以及所需要的")
fmt.Println("..changeTool <readPath> <writePath> <name>")
}
var strs []string
//命令行传入读取文件
file_bytes, err := ioutil.ReadFile(os.Args[1])
if err != nil {
fmt.Println(err.Error() + "\n")
return
}
//按行读取
lines := strings.Split(string(file_bytes), "\n")
//根据 = 进行切割 ,判断 = 右边有没有//字串,之后进行切割组合
for _, line := range lines {
items := strings.Split(string(line), "=")
for _, item := range items {
if strings.Contains(item, " //") {
items := strings.Split(string(item), " //")
items[0] = strings.Replace(items[0], " ", "", -1)
items[1] = strings.Replace(items[1], " ", "", -1)
str := " " + items[0] + ": " + "\"" + items[1] + "\""
strs = append(strs, str)
}
}
}
// 打开命令行传入的文件,进行追加内容
f, err := os.OpenFile(os.Args[2], os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660)
if err != nil {
fmt.Printf(err.Error() + "\n")
return
}
defer f.Close()
w := bufio.NewWriter(f)
fmt.Fprintln(w, "\n"+os.Args[3]+":")
for _, str := range strs {
fmt.Fprintln(w, str)
}
w.Flush()
fmt.Println("success")
运行go generate
单个运行只需要在对应目录(包)下执行:
go generate
1
即可。
对应有多个目录,且又有多个generate需要执行的,在最上层目录下运行:
go generate ./...
1
即可遍历所有目录并执行(注意不能出错)。
————————————————
版权声明:本文为CSDN博主「西洲。」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44264674/article/details/107780595