go Stringer生成代码工具

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前缀。如PillPlaceboPillAspirin等变量,在String()输出时会去掉前缀。去掉前缀是在生成代码时,去掉前缀,而不是调用String()的时候过滤掉前缀。

//go:generate stringer -type=Pill -trimprefix
type Pill int

const (
    PillPlacebo       Pill          = iota // 皮尔
    PillAspirin                            // 阿司匹林
    PillIbuprofen                          // 爱布洛芬
    Paracetamol                        // 帕拉斯塔莫
    Acetaminophen = Paracetamol        // 艾斯塔米诺芬
)

总结

1. stringer 命令只能处理整型的数据类型,像字符串、浮点、布尔类型的都不能用。
2. stringer 可以提高写代码的效率,因为代码是生成的,按照其规则就可以生成,很方便。

你可能感兴趣的:(go Stringer生成代码工具)