go stringer 命令
官方文档
Stringer
是一个自动生成fmt.Stringer
接口的代码的工具。只要给出一个包含常量定义的整型数据类型,stringer
就会为它实现一个方法String() string
。
安装命令
Stringer
命令不是go安装包自带的,所以需要手动下载/安装
# 下载命令
go get golang.org/x/tools/cmd/stringer
# 安装命令
go install golang.org/x/tools/cmd/stringer
注意:stringer
命令所在的目录,需要加入到环境变量PATH
里面
实例
定义一个数据类型Pill
,接着声明几个Pill
类型的常量
//go:generate stringer -type=Pill
type Pill int
const (
Placebo Pill = iota // 皮尔
Aspirin // 阿司匹林
Ibuprofen // 爱布洛芬
Paracetamol // 帕拉斯塔莫
Acetaminophen = Paracetamol // 艾斯塔米诺芬
)
当我们执行stringer -type=Pill
命令时,它就能生成实现了String()
的代码,生成代码如下:
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[Placebo-0]
_ = x[Aspirin-1]
_ = x[Ibuprofen-2]
_ = x[Paracetamol-3]
}
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 "Pill(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _Pill_name[_Pill_index[i]:_Pill_index[i+1]]
}
现在来打印 Placebo
的话,输出的不是数值0
。因为fmt.Println
会先判断这个参数是否实现了String()
函数,如果有的话就会调用改函数做输出。恰好,刚才的stringer
命令已经帮我们生成带String()
的代码。
func main() {
fmt.Println(Placebo)
}
输出结果
Placebo
参数说明
参数 | 说明 |
---|---|
type | 自定义的参数类型 |
output | 生成代码文件名,默认名是{type}_string.go |
linecomment | 取常量所以行的备注,作为打印输出信息 |
trimprefix | 去掉常量名的前缀 |
tags | tags |
type
type
指定了需要generate的对象,后面加文件名的话,就是指定对象所在的文件名
stringer -type=Pill pill.go
output
stringer -type=Pill -output=pill_string.go
linecomment
//go:generate stringer -type=Pill -linecomment
type Pill int
const (
Placebo Pill = iota // 皮尔
Aspirin // 阿司匹林
Ibuprofen // 爱布洛芬
Paracetamol // 帕拉斯塔莫
Acetaminophen = Paracetamol // 艾斯塔米诺芬
)
生成的函数,会以行注释作为string输出
const _Pill_name = "皮尔阿司匹林爱布洛芬帕拉斯塔莫"
var _Pill_index = [...]uint8{0, 6, 18, 30, 45}
func (i Pill) String() string {
if i < 0 || i >= Pill(len(_Pill_index)-1) {
return "Pill(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _Pill_name[_Pill_index[i]:_Pill_index[i+1]]
}
trimprefix
如果常量名称都包含Pill
前缀的话,-trimprefix
选项会在生成代码时,去掉Pill
前缀。如PillPlacebo
、PillAspirin
等变量,在String()输出时会去掉前缀。去掉前缀是在生成代码时,去掉前缀,而不是调用String()
的时候过滤掉前缀。
//go:generate stringer -type=Pill -trimprefix
type Pill int
const (
PillPlacebo Pill = iota // 皮尔
PillAspirin // 阿司匹林
PillIbuprofen // 爱布洛芬
Paracetamol // 帕拉斯塔莫
Acetaminophen = Paracetamol // 艾斯塔米诺芬
)
总结
1. stringer 命令只能处理整型的数据类型,像字符串、浮点、布尔类型的都不能用。
2. stringer 可以提高写代码的效率,因为代码是生成的,按照其规则就可以生成,很方便。