您的位置:锦懂家 > 生活 > >正文

​generate(Go工具之generate)

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

generate(Go工具之generate)

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

bugstartabugreportbuildcompilepackagesanddependencies
cleanremoveobjectfilesandcachedfiles
docshowdocumentationforpackageorsymbol
envprintGoenvironmentinformation
fixupdatepackagestousenewAPIs
fmtgofmt(reformat)packagesources
generategenerateGofilesbyprocessingsourcegetadddependenciestocurrentmoduleandinstalltheminstallcompileandinstallpackagesanddependencieslistlistpackagesormodulesmodmodulemaintenance
runcompileandrunGoprogramtesttestpackages
toolrunspecifiedgotoolversionprintGoversionvetreportlikelymistakesinpackages

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

Go语言的自动化工具

go generate常用于

自动生成代码

,它可以在代码编译之前根据源代码生成代码。当运行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命令

$gogenerate
GoGoGo!gorummain.go!
amd64darwinmain.go7main

为枚举常量实现String方法

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

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

gogetgolang.org/x/tools/cmd/stringer

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

packagepainkillertypePillintconst(
PlaceboPill=iotaAspirin
Ibuprofen
Paracetamol
Acetaminophen=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=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处使用,具体如下。

总结

本文主要介绍generate是什么,能做什么,如果想深入理解其内在实现逻辑,可以去看Go源码中生成代码的详细过程,例如sort包下通过genzfunc.go实现zfuncversion.go的生成。在Go源码宝库中,可以找到很多相似的实现逻辑,参照如下。

它们利用Go编译器提供的库,包括定义抽象语法树的 go/ast、解析抽象语法树的go/parser、解析用于格式化代码的 go/format、用于Go词法标记的go/token等。解析源文件并按照已有的模板生成新的代码,这一过程和Web 服务中利用模板生成 HTML 文件类似。

总结:减少代码的重复编写,保护头发!!

参考

https://golang.org/cmd/go/

https://blog.golang.org/generate

https://godoc.org/golang.org/x/tools/cmd/stringer

https://docs.google.com/document/d/1V03LUfjSADDooDMhe-_K59EgpTEm3V8uvQRuNMAEnjg/edit#

标签:

推荐阅读

  • ​支付宝怎么买东西(支付宝怎么买东西送人)

    支付宝怎么买东西(支付宝怎么买东西送人) 本篇文章给大家谈谈支付宝怎么买东西,以及支付宝怎么买东西送人对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。 怎样用...

    2024-01-18 23:55:43
  • ​阳马(阳马鳖臑示意图)

    阳马(阳马鳖臑示意图) 阳马和鳖臑是什么鬼什么意思 阳马,亦称角梁。中国古代建筑的一种构件。用于四阿(庑殿)屋顶、厦两头(歇山)屋顶转角45°线上,安在各架椽正侧两面交...

    2024-01-18 23:53:37
  • ​夏天去哪旅游好(夏天去哪旅游好玩又便宜)

    夏天去哪旅游好(夏天去哪旅游好玩又便宜) 今天给各位分享夏天去哪旅游好的知识,其中也会对夏天去哪旅游好玩又便宜进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本...

    2024-01-18 23:51:31
  • ​跻身的意思(跻身近义词)

    跻身的意思(跻身近义词) 今天给各位分享跻身的意思的知识,其中也会对跻身近义词进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧! 跻身怎么读 1、跻...

    2024-01-18 23:49:25
  • ​海豚手机浏览器(海豚浏览器apk)

    海豚手机浏览器(海豚浏览器apk) 本篇文章给大家谈谈海豚手机浏览器,以及海豚浏览器apk对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。 什么浏览器可以玩flash页游?...

    2024-01-18 23:47:20
  • ​马红俊魂环搭配加点(马红俊魂环魂技出自哪里)

    马红俊魂环搭配加点(马红俊魂环魂技出自哪里) 大家好,我是正在喝葡萄汁的何二维一。 今天的攻略文章是维一在春节前最后一次给大家总结汇总目前游戏中全魂师的培养优先级和...

    2024-01-18 08:11:53
  • ​us10.5等于中国多少码(us10.5等于中国多少码男)

    us10.5等于中国多少码(us10.5等于中国多少码男) Chinese brands bet on sponsorships at Qatar World Cup “中国元素”闪耀卡塔尔世界杯 A worker arranges the scarves of FIFA World Cup Qatar 2022 in a factory in Hang...

    2024-01-18 08:09:47
  • ​药家鑫事件真实的起因及经过(药家鑫事件真实的起因及经过该如何正确处理)

    药家鑫事件真实的起因及经过(药家鑫事件真实的起因及经过该如何正确处理) 大家好,近期很多朋友对于 药家鑫事件真实的起因及经过 产不是很理解。然后还有一些网友想弄清楚药...

    2024-01-18 08:07:41
  • ​超细纤维和头层牛皮哪个好(鞋子超细纤维和头层牛皮哪个好)

    超细纤维和头层牛皮哪个好(鞋子超细纤维和头层牛皮哪个好) 大家好,近期很多朋友对于 超细纤维和头层牛皮哪个好 产不是很理解。然后还有一些网友想弄清楚鞋子超细纤维和头层...

    2024-01-18 08:05:35
  • ​秦国一共存在了多少年(秦国共多少年历史)

    秦国一共存在了多少年(秦国共多少年历史) 秦王政26年,猛将王贲攻打齐国,齐王建不战而降。到此刻为止,秦完成了统一天下的大业,大秦帝国由此真正建立。 客观地说,结合整个...

    2024-01-18 08:03:30
  • ​适合女人开的车型(女生汽车推荐)

    适合女人开的车型(女生汽车推荐) 大家好,近期很多朋友对于 适合女人开的车型 产不是很理解。然后还有一些网友想弄清楚女生汽车推荐,(www)已经为你找到了相关问题的答案,...

    2024-01-18 08:01:24
  • ​苹果手机声音小怎么办已经调到最大(苹果手机音量开满还声音小)

    苹果手机声音小怎么办已经调到最大(苹果手机音量开满还声音小) 看起来iOS 17将是一个比我们最初想象的更大的iPhone更新,但在这之前,我们还可以期待iOS 16.4,而这个更新刚刚开始...

    2024-01-18 07:59:18
  • ​学什么技术自由还赚钱(什么技术轻松还挣钱)

    学什么技术自由还赚钱(什么技术轻松还挣钱) 短视频带货、直播带货、在线接单修图、开工作室……时间自由、收入更高的灵活就业,正在成为年轻人的就业新选择。90后许剑侠便是其...

    2024-01-18 07:57:12
  • ​神仙鱼的养殖方法和注意事项(神仙鱼怎么分公母)

    神仙鱼的养殖方法和注意事项(神仙鱼怎么分公母) 【渔夫观点】: 燕鱼,它是一种来自南美洲的热带鱼,燕鱼有一个很受鱼友喜爱的点,当他们顺利配对并且有自己的领地,然后产...

    2024-01-18 07:55:07
  • ​中国好声音第一季冠军(中国好声音第一季冠军之夜总决赛)

    中国好声音第一季冠军(中国好声音第一季冠军之夜总决赛) 大家好,近期很多朋友对于中国 好声音第一季冠军 产不是很理解。然后还有一些网友想弄清楚中国好声音第一季冠军之夜...

    2024-01-18 07:53:01
  • ​怎样提高候补车票成功率,教你提高75%购票成功率

    怎样提高候补车票成功率,教你提高75%购票成功率 今年春运期间 候补票兑现成功率达到75%左右 这个数据是不是惊到你? 小伙伴们 12306的购票功能 一直在不断完善 12306的“候补”功能...

    2024-01-16 16:12:22
  • ​R74800H是什么水平的处理器?

    R74800H是什么水平的处理器? 高考结束了! 准备上大学了,一台笔记本电脑必不可少,而一台游戏本更是笔记本中的万能战斗机!今天给大推荐一下618值得入手的几款游戏本! 第一款:...

    2024-01-16 16:10:16
  • ​48ttws(大妹子影视剧在线看免费高清)

    48ttws(大妹子影视剧在线看免费高清) 1、48ttws 48TWS是指采用蓝牙无线技术的48小时耳机。随着移动音乐的普及以及人们对便捷性和音质的要求日益增加,48TWS耳机在市场上受到了广泛的关...

    2024-01-16 16:08:10
  • ​oppok5什么时间上市的(oppok5是什么时候上市,上市价格)

    oppok5什么时间上市的(oppok5是什么时候上市,上市价格) 1、oppok5什么时间上市的 OPPO K5是OPPO公司推出的一款智能手机,其上市时间是在2019年10月10日。这款手机在上市之前就备受消费者的关...

    2024-01-16 16:06:04
  • ​注册商标官网入口(介绍注册商标的官方网站入口)

    注册商标官网入口(介绍注册商标的官方网站入口) 当你的公司想要商标维护权益?当你要贴牌卖货?有自己的商标能让你做大做强再现辉煌哦,看完教程你立马就会了! 第一步:打开...

    2024-01-16 16:03:58