我有一个嵌套的结构。
type ConfigOne struct { // Daemon section from config file. Daemon daemon } type daemon struct { Loglevel int Logfile string }
我有一个String() string关于该类型的方法,我试图将嵌套的struct元素返回为
String() string
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)…
运行时: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。( .handleMethods(0xc42abd6300、0xc400000076、0x410301)
最后,在死亡之前
modules / structs.go:31 + 0xc0 fp = 0xc440103d18 sp = 0xc440103ca8 …删除了其他框架… goroutine 17 [系统调用,锁定到线程]:runtime.goexit()
modules / structs.go:31 + 0xc0 fp = 0xc440103d18 sp = 0xc440103ca8 …删除了其他框架…
goroutine 17 [系统调用,锁定到线程]:runtime.goexit()
我认为这是由于进行了一些无限递归而引起的。
我尽力寻找原因,并到达了这里,我相信这是同样的问题。但是我不明白该线程中的解释。
如果我尝试将单个嵌套结构打印为
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()一种方法是如何导致无限递归和stackoverflow的吗?克服这种情况的最佳方法是什么?
String()
在%v和%+v格式使用的值,String()如果类型实现它。因此,%+v在String()函数中的类型上使用该类型会导致无限递归。不用%+v在String()函数中使用,您必须构造自己的字符串,以您认为合适的任何方式显示结构的内容。
%v
%+v