2025年stringer的使用

stringer的使用更多好文请关注 v golang 技术实验室 作用 stringer 命令旨在自动创建满足 fmt Stringer 的方法 它为指定类型生成 String 并将其描述为字符串 常可用于定义错误码时同时生成错误信息等场景 平时开发中我们都会有映射的需求 一般我们这么做 package main import fmt

大家好,我是讯享网,很高兴认识大家。

作用

stringer命令旨在自动创建满足fmt.Stringer的方法。它为指定类型生成String()并将其描述为字符串。常可用于定义错误码时同时生成错误信息等场景。

平时开发中我们都会有映射的需求,一般我们这么做

package main import "fmt" const ( One = iota Two Three ) //key 和value的映射 var Mp = map[int]string{ 
    One: "one", Two: "two", Three: "three", } func main(){ 
    var is int is = 1 if is == Two{ 
    fmt.Println(Mp[Two]) } } 

讯享网

输出

讯享网-> % go run main.go two 

2、stringer

安装

go get golang.org/x/tools/cmd/stringer 

生成映射文件

讯享网stringer -type=IntModel -rw-r--r-- 1 zhangsan staff 624B Jun 17 13:41 intmodel_string.go -rw-r--r-- 1 zhangsan staff 92B Jun 17 13:41 main.go 

stringer也可以与生成命令完美配合,使其功能更加强大。只需在代码中添加以下指令即可:

//go:generate stringer -type=IntModel 

然后,运行go generate命令将自动为您的所有类型生成新函数。

讯享网Flags: -linecomment use line comment text as printed text when present -output string output file name; default srcdir/<type>_string.go -tags string comma-separated list of build tags to apply -trimprefix prefix trim the prefix from the generated constant names -type string comma-separated list of type names; must be set 

可以指定文件名

我们来看下内容

// Code generated by "stringer -type=IntModel"; DO NOT EDIT. package main 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[One-0] _ = x[Two-1] _ = x[Three-2] } const _IntModel_name = "OneTwoThree" var _IntModel_index = [...]uint8{ 
   0, 3, 6, 11} func (i IntModel) String() string { 
    if i < 0 || i >= IntModel(len(_IntModel_index)-1) { 
    return "IntModel(" + strconv.FormatInt(int64(i), 10) + ")" } return _IntModel_name[_IntModel_index[i]:_IntModel_index[i+1]] } 

在这里插入图片描述
讯享网

3、验证

讯享网package main import ( "fmt" "strconv" ) type IntModel int const ( One IntModel = iota Two Three ) func main(){ 
    p := Two var is int is = 1 if p == IntModel(is){ 
    fmt.Println(p) } } 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[One-0] _ = x[Two-1] _ = x[Three-2] } const _IntModel_name = "OneTwoThree" var _IntModel_index = [...]uint8{ 
   0, 3, 6, 11} func (i IntModel) String() string { 
    if i < 0 || i >= IntModel(len(_IntModel_index)-1) { 
    return "IntModel(" + strconv.FormatInt(int64(i), 10) + ")" } return _IntModel_name[_IntModel_index[i]:_IntModel_index[i+1]] } 
-> % go run main.go Two 

在string包中,只要实现了String,fmt.println()就会自动调用String,fmt.Printf也会

4、对比

讯享网func Switch(i int )string{ 
    switch i { 
    case 0: return "one" case 1: return "two" case 2: return "three" default: return "" } } 

或者if分操作对比发现

这是一个包含二十个值的列表的基准:

name time/op Stringer-4 4.16ns ± 2% StringerWithSwitch-4 3.81ns ± 1% 

这是具有一百个值的基准:

讯享网name time/op Stringer-4 4.96ns ± 0% StringerWithSwitch-4 4.99ns ± 1% 

拥有的常数越多,效率越高。这实际上是有道理的。从内存中加载值比执行一些跳转指令(表示if条件的汇编指令)要耗费更多的时间。但是,switch越大,跳转指令的数量就越大。从某个角度来看,从内存中加载将变得更加有效。

自检

在生成的指令中,仅出于验证目的而创建了一些指令。以下是这些说明:

在这里插入图片描述

stringer将每行的常量名称与该值一起写入。在此示例中,Aspirin的值为2。更新常量名称或其值将生成错误:

  • 更新名称而不重新生成String()函数:
  • 更新值而不重新生成String()函数:
# command-line-arguments ./main.go:30:7: invalid array index One - 0 (out of bounds for 1-element array) ./main.go:31:7: invalid array index Two - 1 (out of bounds for 1-element array) ./main.go:32:7: invalid array index Three - 2 (out of bounds for 1-element array) 

但是,如果我们添加一个新的常量(这里的下一个键是数字3)并且不更新生成的文件,则stringer具有默认值:

讯享网IntModel(3) 

添加此自检不会产生任何影响,因为在编译时将其删除。可以通过查看程序生成的asm代码来确认:

➜ go tool compile -S main.go pill_string.go | grep "\"\".IntModel\.[^\s]* STEXT" "".Pill.String STEXT size=275 args=0x18 locals=0x50 

只有String()函数以二进制形式导出。该检查没有性能或二进制大小的开销。

小讯
上一篇 2025-03-13 17:25
下一篇 2025-02-25 23:33

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/53906.html