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