Iteracja przez pola struktury w Go

Zasadniczo, jedynym sposobem (jaki znam) na iterację przez wartości pól struct jest tak:

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 na osiągnięcie []interface{}{ r.a_number, r.a_string, }, więc nie muszę wymieniać każdego parametru indywidualnie, lub alternatywnie, czy istnieje lepszy sposób na pętlę przez strukturę?

Próbowałem spojrzeć przez reflect pakiet, ale trafiłem w ścianę, bo nie wiem, co zrobić, gdy odzyskam reflect.ValueOf(*r).Field(0).

Dzięki!
Author: kostix, 2013-09-21

1 answers

Po pobraniu reflect.Value Pola za pomocą Field(i) możesz uzyskać wartość interfejsu z niego wywołując Interface(). Wspomniana wartość interfejsu reprezentuje wtedy wartość pola.

Nie ma funkcji konwertującej wartość pola na konkretny typ, ponieważ są, jak zapewne wiesz, żadnych generyków w go. Tak więc, nie ma funkcji z podpisem GetValue() T gdzie T jest typem tego pola (co oczywiście zmienia się w zależności od pola).

The closest you can osiągnąć w go jest GetValue() interface{} i to jest dokładnie to, co reflect.Value.Interface() oferty.

Poniższy kod ilustruje, jak uzyskać wartości każdego eksportowanego pola w strukturze using reflection (play):

import (
    "fmt"
    "reflect"
)

func main() {
    x := struct{Foo string; Bar int }{"foo", 2}

    v := reflect.ValueOf(x)

    values := make([]interface{}, v.NumField())

    for i := 0; i < v.NumField(); i++ {
        values[i] = v.Field(i).Interface()
    }

    fmt.Println(values)
}
 66
Author: nemo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-01 21:46:40