go generate介绍及使用

Go generate 是Go 1.4版本引入的工具,用于在构建前自动生成特定文件。本文通过一个实例展示了如何使用gogenerate结合自定义脚本,将代码中的状态码常量转换为.yaml格式的语言包,实现自动化代码生成和维护。
摘要由CSDN通过智能技术生成

转载地址: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值