Zasadniczo jedyny sposób (jaki znam) na iterację wartości pól a struct
jest taki:
type Example struct {
a_number uint32
a_string string
}
//...
r := &Example{(2 << 31) - 1, "...."}:
for _, d:= range []interface{}{ r.a_number, r.a_string, } {
//do something with the d
}
Zastanawiałem się, czy istnieje lepszy i bardziej wszechstronny sposób osiągnięcia tego celu []interface{}{ r.a_number, r.a_string, }
, więc nie muszę osobno wymieniać każdego parametru, czy też alternatywnie, czy istnieje lepszy sposób na zapętlenie przez strukturę?
Próbowałem przejrzeć reflect
paczkę, ale uderzyłem w ścianę, ponieważ nie jestem pewien, co zrobić po odzyskaniu reflect.ValueOf(*r).Field(0)
.
Dzięki!
go
go-reflect
omninonsense
źródło
źródło
Odpowiedzi:
Po pobraniu
reflect.Value
pola za pomocąField(i)
można uzyskać z niego wartość interfejsu, wywołującInterface()
. Wspomniana wartość interfejsu reprezentuje wówczas wartość pola.Nie ma funkcji do konwersji wartości pola na konkretny typ, ponieważ, jak być może wiesz, nie ma żadnych typów ogólnych. Tak więc, nie ma funkcji z podpisem
GetValue() T
zT
bycia typem tej dziedzinie (która zmienia się oczywiście w zależności od dziedziny).Najbliższe jest
GetValue() interface{}
to, co możesz osiągnąć w ruchu i właśnie toreflect.Value.Interface()
oferuje.Poniższy kod ilustruje, jak uzyskać wartości każdego eksportowanego pola w strukturze przy użyciu refleksji ( odtwarzania ):
źródło
reflect.Value.Type()
, tak. Należy jednak pamiętać, że typy nie są obywatelami pierwszej klasy w ruchu, więc nowe wystąpienia tego typu można tworzyć tylko przy użyciureflect
.v.Field(i).Interface()
paniki, jeśli spróbujesz uzyskać dostęp do niewyeksportowanych pól prywatnych. Tylko uważaj :)v.Field(i).CanInterface()
pozwala uniknąć paniki w przypadku niewyeksportowanych pól.Jeśli chcesz iterować przez pola i wartości struktury, możesz użyć poniższego kodu Go jako odniesienia.
Biegnij na placu zabaw
Uwaga: Jeśli pola w twojej strukturze nie są eksportowane,
v.Field(i).Interface()
wywoła panikępanic: reflect.Value.Interface: cannot return value obtained from unexported field or method.
źródło
Przyjmowanie roztworu Chetan Kumar i na wypadek konieczności zastosowania się do
map[string]int
źródło