2017-03-04 15 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 +0xc0 fp=0xc440103d18 sp=0xc440103ca8 
...additional frames elided... 

goroutine 17 [syscall, locked to thread]: 
runtime.goexit() 

일부 무한 재귀로 이동하여 발생, 사망하기 전에 마지막으로 한

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) 

아래에 유사한 라인을 반복적으로 볼 수 있었다.

나는 운을내어 원인을 찾았고, here에 도착했다. 그것은 같은 이슈 다라고 생각한다. 그러나 그 스레드의 설명을 이해할 수 없었다.

나는

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

그것이 잘 작동으로 개별 중첩 된 구조체를 인쇄하려고 및 로그는 이전 String() 방법은 결과가 얼마나 사람이 친절하게 설명 할 수

2017/03/05 01:28:25 go-consume.go:38: INFO: {Loglevel:1 Logfile:/tmp/test.log} 

로 필드를 표시하는 경우 무한 재귀와 stackoverflow, 그리고 이것을 극복하는 가장 좋은 방법은 무엇입니까? 유형을 구현하는 경우

답변

5

%v%+v 형식 String()의 값을 사용한다. 따라서 해당 형식에 String() 함수 내의 형식에 %+v을 사용하면 무한 재귀가 발생합니다. String() 함수에서 %+v을 사용하는 대신 사용자가 원하는대로 문자열을 구성하여 구조의 내용을 표시해야합니다.

+0

감사합니다. @ andy-schweig. – nohup