我有一个嵌套的结构。
type ConfigOne struct {
// Daemon section from config file.
Daemon daemon
}
type daemon struct {
Loglevel int
Logfile string
}
我在该类型上有一个String() string
方法,我试图将嵌套的struct元素作为
func (c ConfigOne)String() string{
return fmt.Sprintf("%+v\n", c)
}
当我尝试将其打印为
时c := &modules.ConfigOne{}
c.Daemon.Loglevel = 1
c.Daemon.Logfile = "/tmp/test.log"
modules.Logger.Infoln(c.String())
我收到错误
运行时:goroutine堆栈超过1000000000字节限制 致命错误:堆栈溢出
运行时堆栈: runtime.throw(0x6ea3b7,0xe) ...
在完成错误后,我可以看到类似于下面的重复行
modules / structs.go:31 + 0x77 fp = 0xc440100398 sp = 0xc440100328 go-consume / modules。(* ConfigOne).String(0xc42abcb4e0,0x70bc08,0xc42abd6300) :1 + 0x64 fp = 0xc4401003d8 sp = 0xc440100398 fmt。(* pp).handleMethods(0xc42abd6300,0xc400000076,0x410301)
最后,在临死前,
modules / structs.go:31 + 0xc0 fp = 0xc440103d18 sp = 0xc440103ca8 ...其他框架已被淘汰......
goroutine 17 [系统调用,锁定到线程]: runtime.goexit()
我认为这是由于进入一些无限递归引起的。
我试着运气找到原因并达到了here,我认为这是同样的问题。但是我无法理解那个帖子中的解释。
如果我尝试将单个嵌套结构打印为
func (c ConfigOne)String() string{
//return fmt.Sprintf("%+v\n", c.Daemon.Loglevel)
return fmt.Sprintf("%+v\n", c.Daemon)
}
它工作正常,日志将字段显示为
2017/03/05 01:28:25 go-consume.go:38: INFO: {Loglevel:1 Logfile:/tmp/test.log}
有人可以解释前String()
方法如何导致无限递归和堆栈溢出,以及解决此问题的最佳方法是什么?
答案 0 :(得分:9)
如果类型实现了%v
和%+v
格式,则使用String()
的值。因此,对该类型的%+v
函数中的类型使用String()
会导致无限递归。您不必在%+v
函数中使用String()
,而是必须构建自己的字符串,以您认为合适的方式显示结构的内容。