Golang noob问题:为什么我不在String()实现方法中使用"%+v"
标志作为结构?
我有一个结构,我希望为漂亮的打印实现String()
方法。我喜欢here给出的答案,但我不想输入,因此我尝试修改它以使用结构的"%+v"
格式标志返回字符串。来自fmt doc:
%v打印结构时的默认格式值,加号标志 (%+ v)添加字段名称
如果我只是用fmt.Printf("%+v", color)
调用它,这可以正常工作,但是如果我尝试将+
标志放在String()
实现中,我会得到堆栈溢出(我第一次有机会在stackoverflow.com上询问堆栈溢出"问题;))
我确定我不理解这里的指针引用,或者有一些递归。我怀疑这个菜鸟找到了我的第一个Golang虫子,所以有人可以解释一下吗?
请参阅此处的演示演示https://play.golang.org/p/13_qI8Iwwa
答案 0 :(得分:6)
请参阅Package fmt Docs:
除非使用动词
%T
和%p
打印,否则为特殊格式 注意事项适用于实现某些接口的操作数。 按申请顺序:
- 如果操作数实现方法
醇>String() string
,则将调用该方法将对象转换为字符串,然后将该字符串 根据动词的要求格式化(如果有的话)。避免在
等情况下递归type X string func (x X) String() string { return Sprintf("<%s>", x) }
在重复之前转换值:
func (x X) String() string { return Sprintf("<%s>", string(x)) }
无限递归也可以由自引用数据触发 结构,例如包含自身作为元素的切片,if 该类型具有String方法。然而,这种病症很少见 包裹不能防止它们。
内部:
func (c Color) String() string {
// THIS CAUSES STACK OVERFLOW
return fmt.Sprint(c)
}
致电
fmt.Sprint(c)
再次以递归方式调用fmt.Println(c)
的或func (c Color) String() string
导致溢出:在The Go Playground上尝试