I have a project
function which returns a slice containing the field values by name of each struct or map in an input slice. I am having trouble with case where the input slice contains pointers to structs. I have setup a recursive function to operate on the value, but need to know how to convert from kind reflect.Ptr
to the underlying reflect.Struct
. How is this done? Any other design recommendations are appreciated. I am still a bit new to Go.
Here is the code:
func project(in []interface{}, property string) []interface{} {
var result []interface{}
var appendValue func(list []interface{}, el interface{})
appendValue = func(list []interface{}, el interface{}) {
v := reflect.ValueOf(el)
kind := v.Kind()
if kind == reflect.Ptr {
// How do I get the struct behind this ptr?
// appendValue(list, el)
} else if kind == reflect.Struct {
result = append(result, v.FieldByName(property).Interface())
} else if kind == reflect.Map {
result = append(result, el.(map[string]interface{})[property])
} else {
panic("Value must be a struct or map")
}
}
for _, el := range in {
appendValue(result, el)
}
return result
}
... and the test cases:
func Test_project(t *testing.T) {
cases := map[string]struct {
input []interface{}
property string
expected []interface{}
}{
"simple-map": {
[]interface{}{
map[string]interface{}{
"a": "a1",
},
},
"a",
[]interface{}{"a1"},
},
"simple-struct": {
[]interface{}{
simpleStruct{
A: "a1",
},
},
"A",
[]interface{}{"a1"},
},
// THIS ONE FAILS
"simple-struct-ptr": {
[]interface{}{
&simpleStruct{
A: "a1",
},
},
"A",
[]interface{}{"a1"},
},
}
for k, v := range cases {
t.Run(k, func(t *testing.T) {
got := project(v.input, v.property)
if !reflect.DeepEqual(got, v.expected) {
t.Fatalf("Expected %+v, got %+v", v.expected, got)
}
})
}
}
Aucun commentaire:
Enregistrer un commentaire