2017-03-04 291 views
2

我有一个嵌套结构。运行时:goroutine堆栈超过1000000000字节限制,致命错误:打印嵌套结构时发生堆栈溢出

type ConfigOne struct { 
// Daemon section from config file. 
Daemon daemon 
} 
type daemon struct { 
Loglevel int 
Logfile string 
} 

而且我对这种类型的,而我试图当我尝试打印它作为

c := &modules.ConfigOne{} 
c.Daemon.Loglevel = 1 
c.Daemon.Logfile = "/tmp/test.log" 
modules.Logger.Infoln(c.String()) 

返回嵌套的结构元素

func (c ConfigOne)String() string{ 
return fmt.Sprintf("%+v\n", c) 
} 

一个String() string方法我得到错误

runtime: goroutine stack exceeds 1000000000-byte limit 
fatal error: stack overflow 

runtime stack: 
runtime.throw(0x6ea3b7, 0xe) 
... 

通过误差会后,我可以看到重复的行类似下面的一个

modules/structs.go:31 +0x77 fp=0xc440100398 sp=0xc440100328 
go-consume/modules.(*ConfigOne).String(0xc42abcb4e0, 0x70bc08, 0xc42abd6300) 
<autogenerated>:1 +0x64 fp=0xc4401003d8 sp=0xc440100398 
fmt.(*pp).handleMethods(0xc42abd6300, 0xc400000076, 0x410301) 

最后,临终前,

modules/structs.go:31 +0xc0 fp=0xc440103d18 sp=0xc440103ca8 
...additional frames elided... 

goroutine 17 [syscall, locked to thread]: 
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()方法是如何产生的在一个无限的递归和一个stackoverflow中,什么是克服这个问题的最好方法?

回答

5

如果类型实现它,则%v%+v格式将使用值String()。因此,在该类型的String()函数内使用%+v会导致无限递归。 String()函数不是使用%+v,而是必须构建自己的字符串,以任何您认为合适的方式显示结构的内容。

+0

谢谢@ andy-schweig。 – nohup