美文网首页
go Stringer生成代码工具

go Stringer生成代码工具

作者: GUIN蚂蚁 | 来源:发表于2022-07-26 17:20 被阅读0次

    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生成代码工具

          本文链接:https://www.haomeiwen.com/subject/timzirtx.html