fmt.Println은 내장 유형을 편리하게 표시하지만 구조체에 대한 동작은 장황하고 유익하지 않을 수 있습니다. 추가 필드가 있는 시간 값을 나타내는 구조체를 생각해 보세요.
type A struct { t time.Time }
fmt.Println을 사용하여 이 구조체를 인쇄하면 다음과 같은 결과가 나옵니다.
{{63393490800 0 0x206da0}}
쉽게 해석할 수 없습니다. 특히 구조체에는 String() 메서드가 부족하여 해당 필드가 원하는 대로 형식화되지 않습니다.
문제:
사용자 정의 문자열로 구조체를 인쇄하려면 어떻게 해야 합니까? 각각에 대해 String() 메서드를 명시적으로 정의하지 않고 해당 필드에 대한 표현 struct?
해결책:
리플렉션을 사용하여 구조체의 필드를 반복하고 해당 String() 메서드를 동적으로 호출할 수 있습니다. 이를 수행하는 도우미 함수는 다음과 같습니다.
func PrintStruct(s interface{}, names bool) string { v := reflect.ValueOf(s) t := v.Type() // Handle non-struct input if t.Kind() != reflect.Struct { return fmt.Sprint(s) } // Initialize buffer b := &bytes.Buffer{} b.WriteString("{") for i := 0; i < v.NumField(); i++ { if i > 0 { b.WriteString(" ") } v2 := v.Field(i) if names { b.WriteString(t.Field(i).Name) b.WriteString(":") } // Handle Stringer fields if v2.CanInterface() { if st, ok := v2.Interface().(fmt.Stringer); ok { b.WriteString(st.String()) continue } } // Print non-Stringer fields fmt.Fprint(b, v2) } b.WriteString("}") // Return formatted string return b.String() }
사용법:
이 함수는 사용자 정의 필드가 있는 구조체를 인쇄하는 데 사용할 수 있습니다. 형식 지정:
a := A{time.Now()} fmt.Println(PrintStruct(a, true)) // Display field names fmt.Println(PrintStruct(a, false)) // Omit field names
참고:
추가 편의를 위해 단순히 호출하는 구조체에 대한 String() 메서드를 정의할 수 있습니다. PrintStruct:
func (a A) String() string { return PrintStruct(a, true) }
위 내용은 각 구조체에 대해 String() 메서드를 명시적으로 정의하지 않고 Go 구조체의 인쇄를 사용자 정의하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!