简体   繁体   English

当值属于reflect.Ptr类型时,如何使用reflect.FieldByName

[英]How do I use reflect.FieldByName when the value is of kind reflect.Ptr

I have a project function which returns a slice containing the field values by name of each struct or map in an input slice. 我有一个project函数,该函数返回一个切片,该切片包含输入切片中每个结构或映射的名称的字段值。 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 . 我已经设置了一个递归函数来对值进行操作,但是需要知道如何将kind从reflect.Ptr转换为基础的reflect.Struct How is this done? 怎么做? Any other design recommendations are appreciated. 任何其他设计建议,不胜感激。 I am still a bit new to Go. 我对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)
            }
        })
    }
}

使用Elem()reflect.Ptr转到它指向的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM