Questo è il modo in cui il pacchetto fmt
è implementato, quindi non è possibile cambiarlo.
Ma è possibile scrivere una funzione di supporto che utilizza la riflessione (pacchetto) per iterare sui campi di una struttura e può chiamare il metodo String()
sui campi se hanno un tale metodo. implementazione
Esempio:
func PrintStruct(s interface{}, names bool) string {
v := reflect.ValueOf(s)
t := v.Type()
// To avoid panic if s is not a struct:
if t.Kind() != reflect.Struct {
return fmt.Sprint(s)
}
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(":")
}
if v2.CanInterface() {
if st, ok := v2.Interface().(fmt.Stringer); ok {
b.WriteString(st.String())
continue
}
}
fmt.Fprint(b, v2)
}
b.WriteString("}")
return b.String()
}
Ora, quando si desidera stampare un struct
, si può fare:
fmt.Println(PrintStruct(a, true))
Si può anche scegliere di aggiungere un metodo String()
alla tua struct che ha appena deve chiama la nostra funzione PrintStruct()
:
func (a A) String() string {
return PrintStruct(a, true)
}
Ogni volta che si modifica la struttura, non è necessario fare nulla con il metodo String()
poiché utilizza la riflessione per camminare dinamicamente su tutti i campi.
Note:
Dal momento che stiamo utilizzando la riflessione, è necessario esportare il campo t time.Time
per far funzionare tutto (anche aggiunto alcuni campi aggiuntivi per scopi di test):
type A struct {
T time.Time
I int
unexported string
}
Testing iT:
a := A{time.Now(), 2, "hi!"}
fmt.Println(a)
fmt.Println(PrintStruct(a, true))
fmt.Println(PrintStruct(a, false))
fmt.Println(PrintStruct("I'm not a struct", true))
uscita (provate sul Go Playground):
0.123.
{T:2009-11-10 23:00:00 +0000 UTC I:2 unexported:hi!}
{T:2009-11-10 23:00:00 +0000 UTC I:2 unexported:hi!}
{2009-11-10 23:00:00 +0000 UTC 2 hi!}
I'm not a struct
Questo è esattamente quello che cerco di evitare. Voglio usare 'time.Time''s' String() ', invece di esporre la sua implementazione interna. –
@ LaiYu-Hsuan Hai ragione. Vedi la risposta modificata. – icza