runtime: goroutine stack exceeds 1000000000-byte limit, fatal error: stack overflow on printing a nested struct
runtime: goroutine stack exceeds 1000000000-byte limit, fatal error: stack overflow on printing a nested struct
我有一个嵌套结构。
type ConfigOne struct {
// Daemon section from config file.
Daemon daemon
}
type daemon struct {
Loglevel int
Logfile string
}
而且我在该类型上有一个 String() string
方法,我试图将其 return 嵌套结构元素作为
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())
我遇到错误
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)
: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()
方法是如何导致无限递归和计算器溢出的,克服这个问题的最佳方法是什么?
如果类型实现了 %v
和 %+v
格式,则使用 String()
的值。因此,在该类型的 String()
函数中对该类型使用 %+v
会导致无限递归。您不必在 String()
函数中使用 %+v
,而是必须构建自己的字符串,以您认为合适的任何方式显示结构的内容。
我有一个嵌套结构。
type ConfigOne struct {
// Daemon section from config file.
Daemon daemon
}
type daemon struct {
Loglevel int
Logfile string
}
而且我在该类型上有一个 String() string
方法,我试图将其 return 嵌套结构元素作为
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())
我遇到错误
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) :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()
方法是如何导致无限递归和计算器溢出的,克服这个问题的最佳方法是什么?
如果类型实现了 %v
和 %+v
格式,则使用 String()
的值。因此,在该类型的 String()
函数中对该类型使用 %+v
会导致无限递归。您不必在 String()
函数中使用 %+v
,而是必须构建自己的字符串,以您认为合适的任何方式显示结构的内容。