我有一个project
函数,该函数返回一个切片,该切片包含输入切片中每个结构或映射的名称的字段值。我在输入切片包含指向结构的指针的情况下遇到麻烦。我已经设置了一个递归函数来对值进行操作,但是需要知道如何将类型reflect.Ptr
转换为基础reflect.Struct
。怎么做?任何其他设计建议,不胜感激。我对Go还是有点陌生。
代码如下:
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
}
...和测试用例:
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)
}
})
}
}