go generate
介绍
go generate 命令是go 1.4版本里面新添加的一个命令,当运行 go generate 时,它将扫描与当前包相关的源代码文件,找出所有包含 //go:generate 的特殊注释,提取并执行该特殊注释后面的命令,命令为可执行程序,形同shell下面执行。
有几点需要注意:
- 该特殊注释必须在
.go源码文件中。 - 每个源码文件可以包含多个
generate特殊注释时。 - 显示运行
go generate命令时,才会执行特殊注释后面的命令。 - 命令串行执行的,如果出错,就终止后面的执行。
- 特殊注释必须以
//go:generate开头,双斜线后面没有空格。
应用
在有些场景下,我们会使用 go generate :
- yacc:从 .y 文件生成 .go 文件。
- protobufs:从 protocol buffer 定义文件(.proto)生成 .pb.go 文件。
- Unicode:从 UnicodeData.txt 生成 Unicode 表。
- HTML:将 HTML 文件嵌入到 go 源码 。
- bindata:将形如 JPEG 这样的文件转成 go 代码中的字节数组。
再比如:
- string方法:为类似枚举常量这样的类型生成String()方法。
- 宏:为既定的泛型包生成特定的实现,比如用于ints的sort.Ints。
命令
go generate 命令使用格式如下:
go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
其中:
- -run 正则表达式匹配命令行,仅执行匹配的命令
- -v 输出被处理的包名和源文件名
- -n 显示不执行命令
- -x 显示并执行命令
执行 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("main func")
}
执行 go generate 后,输出如下:
$ go generate
hello
main func
file=main.go pkg=main
示例
现在我们来实践一下前面介绍的 go generate。
String()方法
假设我们有一些代码,里面包含若干定义为Pill的整型常量:
package painkiller
type Pill int
const (
Placebo Pill = iota
Aspirin
Ibuprofen
Paracetamol
Acetaminophen = Paracetamol
)
为了调试的需要,我们会为这些常量定义String()签名方法:
func (p Pill) String() string
一般情况下,我们可能会像下面这样写:
func (p Pill) String() string {
switch p {
case Placebo:
return "Placebo"
case Aspirin:
return "Aspirin"
case Ibuprofen:
return "Ibuprofen"
case Paracetamol: // == Acetaminophen
return "Paracetamol"
}
return fmt.Sprintf("Pill(%d)", p)
}
这里,我们可以用 go generate 来实现String():
首先,我这里创建一个painkiller.go文件,包含如下内容:
//go:generate stringer -type=Pill
package painkiller
type Pill int
const (
Placebo Pill = iota
Aspirin
Ibuprofen
Paracetamol
Acetaminophen = Paracetamol
)
在文件的开头包含了一个 //go:generate stringer -type=Pill 特殊注释,其中stringer是个生成String方法的工具,为了使用stringer方法,在运行 go generate 命令前,我们需要安装stringer工具,命令如下:
$ go get golang.org/x/tools/cmd/stringer
然后,在 painkiller.go 所在的目录下面运行 go generate 命令:
$ go generate
我们会发现当前目录下面生成一个pill_string.go文件,里面实现了我们需要的String()方法,文件内容如下:
// 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]]
}
go generate的更多相关文章
- 使用mvn archetype:generate生产maven工程,响应很慢
经常到下列时就不往下走了. 解决方案: 1.不使用interactive mode方式,直接指定DarchetypeArtifactId 2.仍使用interactive mode方式,但增加参数 - ...
- [LeetCode] Generate Parentheses 生成括号
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- LeetCode 22. Generate Parentheses
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- 【leetcode】Generate Parentheses
题目简述: Given n pairs of parentheses, write a function to generate all combinations of well-formed par ...
- 在cmd命令行使用Maven Archetype插件 generate命令创建简单的java web项目
前提: 1.下载apache-maven:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache ...
- No.022:Generate Parentheses
问题: Given n pairs of parentheses, write a function to generate all combinations of well-formed paren ...
- iOS 苹果开发证书失效的解决方案(Failed to locate or generate matching signing assets)
从2月14日开始,上传程序的同学可能会遇到提示上传失败的提示. 并且打开自己的钥匙串,发现所有的证书全部都显示此证书签发者无效. 出现以下情况: Failed to locate or generat ...
- How to generate UML Diagrams from Java code in Eclipse
UML diagrams compliment inline documentation ( javadoc ) and allow to better explore / understand a ...
- maven archetype:generate 命令简化项目模板数量
在maven里使用 mvn archetype:generate 来创建项目是十分方便的,但有时也不尽然.在网络不好时,从网络上加载 archetype-catalog.xml文件(http://re ...
- Generate Time Data(普通日期主数据)
Note: While using this option you need to replicate the standard table into SAP HANA that is T005T, ...
随机推荐
- 【狂神说Java】Java零基础学习笔记-面向对象
[狂神说Java]Java零基础学习笔记-面向对象 面向对象01:什么是面向对象 面向过程&面向对象 面向过程思想 步骤清晰简单,第一步做什么,第二步做什么.... 面对过程适合处理一些较为简 ...
- 从BIOS+MBR迁移到UEFI+GPT 并修复Ubuntu Grub2 UEFI引导
之前在虚拟机里使用了默认配置安装了Ubuntu16.04,由于需要扩充磁盘空间不得不将磁盘从MBR分区表转换到GPT分区表. 简单介绍一下思路:首先通过Windows下的DiskGenius软件备份U ...
- 谈谈flutter的线程
本文同步发布于公众号:移动开发那些事谈谈flutter的线程 刚接触flutter的同学肯定会对fluter所谓的单线程架构很蒙逼,因为这与我们学开发时,各种语言里的多线程的介绍有点出入,而且手机的C ...
- c# 多线程 lock
模拟10个线程,每个线程模拟100次取钱: 其实就是相当于1000个人来同时取钱.当然实际情况是取钱的人分布在不同的地区的取款机取钱.同一个取款机只能一个人操作. 关键是要保证取钱的余额要准确,不能在 ...
- 如何快速的开发一个完整的iOS直播app(采集篇)
作者:袁峥链接:https://www.jianshu.com/p/c71bfda055fa来源:简书著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 开发一款直播app,首先需要 ...
- 告别虚拟机!WSL2安装配置教程!!!
作者:SkyXZ CSDN:SkyXZ--CSDN博客 博客园:SkyXZ - 博客园 由于Linux的系统的稳定以及在环境管理方面的优越性,同时Linux对于ROS系统的独占,很多时候我们都乐意在L ...
- Kotlin:【set集合】集合创建、可变集合mutableSetOf、集合转换(List转换成Set,去掉重复元素)、distinct快捷去重函数、数组
- 微信小程序音频播放
微信小程序音频播放 // 开启播放音频 startAudio(){ const innerAudioContext = uni.createInnerAudioContext();//创建并返回内部 ...
- 2025年这些实用的C#/.NET知识点你都知道吗?
前言 在这个快速发展的技术世界中,时常会有一些重要的知识点.信息或细节被忽略或遗漏.<C#/.NET/.NET Core拾遗补漏>专栏我们将探讨一些可能被忽略或遗漏的重要知识点.信息或细节 ...
- CPU的指令周期
本文分享自天翼云开发者社区<CPU的指令周期>,作者:冯****怡 指令周期(Instruction Cycle) CPU中会有 存器.指令寄存器.控制器等多类单元.指令集,就是CPU中用 ...