go generate命令怎么使用(generate,go,编程语言)

时间:2024-05-09 05:43:20 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

“go generate”命令的作用是在编译前自动化生成某类代码;它常用于自动生成代码,它可以在代码编译之前根据源代码生成代码。当运行“go generate”命令时,它将扫描与当前包相关的源代码文件,找出所有包含“//go:generate”的特殊注释,提取并执行该特殊注释后面的命令。

Go语言提供了一系列强大的工具,灵活使用这些工具,能够让我们的项目开发更加容易,工具集包含如下。

bugstartabugreportbuildcompilepackagesanddependenciescleanremoveobjectfilesandcachedfilesdocshowdocumentationforpackageorsymbolenvprintGoenvironmentinformationfixupdatepackagestousenewAPIsfmtgofmt(reformat)packagesourcesgenerategenerateGofilesbyprocessingsourcegetadddependenciestocurrentmoduleandinstalltheminstallcompileandinstallpackagesanddependencieslistlistpackagesormodulesmodmodulemaintenanceruncompileandrunGoprogramtesttestpackagestoolrunspecifiedgotoolversionprintGoversionvetreportlikelymistakesinpackages

工具的源码位于$GOPATH/src/cmd/internal,本篇文章主要讨论Go工具generate。

go语言自动化工具

go generate命令是在Go语言 1.4 版本里面新添加的一个命令,常用于自动生成代码,它可以在代码编译之前根据源代码生成代码。当运行go generate时,它将扫描与当前包相关的源代码文件,找出所有包含"// go:generate"的注释语句,提取并执行该注释后的命令,命令为可执行程序。该过程类似于调用执行shell脚本。

使用方法

  • 添加特殊注释

//go:generatecommandargument...

  • 执行generate命令

$gogenerate[-runregexp][-n][-v][-x][buildflags][file.go...|packages]

注意事项

  • 该特殊注释必须包含在.go源码文件中。

  • 每个源码文件可以包含多个generate特殊注释。

  • go generate不会被类似go build,go get,go test等命令触发执行,必须由开发者显式使用。

  • 命令执行是串行的,如果出错,后续命令不再执行。

  • 特殊注释必须以“//go:generate”开头,双斜线之后没有空格。

  • 执行命令必须是系统PATH(echo $PATH)下的可执行程序。

使用示例

packagemainimport"fmt"//go:generateechoGoGoGo!//go:generategorunmain.go//go:generateecho$GOARCH$GOOS$GOFILE$GOLINE$GOPACKAGEfuncmain(){fmt.Println("gorummain.go!")}

执行go generate命令

$gogenerateGoGoGo!gorummain.go!amd64darwinmain.go7main

为枚举常量实现String方法

看完上述generate的简单介绍,可能读者并没有感受到该工具的强大之处,小菜刀提供一个该工具的经典应用场景:为枚举常量实现String方法。

这里需要提及官方的另外一个工具stringer,它可以自动为整数常量集编写String()方法。由于stringer并不在Go官方发行版的工具集里,我们需要自行安装,执行如下命令。

gogetgolang.org/x/tools/cmd/stringer

这里引用stringer文档中的一个示例。代码如下,其定义了一组不同Pill类型的整数常量。

packagepainkillertypePillintconst(PlaceboPill=iotaAspirinIbuprofenParacetamolAcetaminophen=Paracetamol)

为了进行调试或者其他原因,我们希望这些常量能够打印出来,这意味着Pill要有一个带有签名的方法。

func(pPill)String()string

要实现它,非常简单。

func(pPill)String()string{switchp{casePlacebo:return"Placebo"caseAspirin:return"Aspirin"caseIbuprofen:return"Ibuprofen"caseParacetamol://==Acetaminophenreturn"Paracetamol"}returnfmt.Sprintf("Pill(%d)",p)}

试想,如果我们的Pill名单里新增了一批药品名,每次增加或修改药品名,在相应的签名函数里,也都需要进行更改。这样岂不是很麻烦且很可能遗漏或出错?这时,我们可以通过 go generate + stringer的方案解决该问题。很简单,只需在定义Pill的代码中,增加一句注释语句即可。

//go:generatestringer-type=Pill

上面的命令,代表运行stringer工具来为Pill类型生成String方法,默认输出到pill_string.go文件中,执行如下。

$gogenerate$catpill_string.go//Codegeneratedbystringer-typePillpill.go;DONOTEDIT.packagepainkillerimport"fmt"const_Pill_name="PlaceboAspirinIbuprofenParacetamol"var_Pill_index=[...]uint8{0,7,14,23,34}func(iPill)String()string{ifi<0||i+1>=Pill(len(_Pill_index)){returnfmt.Sprintf("Pill(%d)",i)}return_Pill_name[_Pill_index[i]:_Pill_index[i+1]]}

这样,每次我们对Pill类型有修改时,我们所需要做的就是运行以下语句即可。

$gogenerate

当然,你要是觉得这样麻烦,或者担心忘记执行generate语句。那么,可以将go generate语句写入Makefile之中,置于go build命令之前,实现代码生成与编译的自动化。

值得一提的是,在Go源码文档中,大量采用了go generate+stringer的方案实现对枚举常量的String方法。在小菜刀本机Go 1.14.1的源码下,一共有23处使用,具体如下。

go generate命令怎么使用

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:go generate命令怎么使用的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:汇编语言是不是高级语言下一篇:

8 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18