通过反射将类型“接口{}”转换为类型“接口{}”的切片中的另一个接口

时间:2019-11-29 18:34:11

标签: go slice

我有一个类型为People的切片,我需要将此切片传递给获取类型为“接口{}”的函数。人员类型“实现”名为HasCustomField的接口,但是我不能像现在那样在函数中进行类型转换:

type HasCustomField interface {
    GetCustomField() map[string]interface{}
}

type People struct {    
    Name string
    customField map[string]interface{}
}

func (c *People) GetCustomField() map[string]interface{} {
    if c.customField == nil {
        c.customField = make(map[string]interface{})
    }
    return c.customField
}

func main() {
    users := []People{{Name:"Teste"},{Name:"Mizael"}}
    ProcessCustomField(&users)
}

func ProcessCustomField(list interface{}) {
    if list != nil {
        listVal := reflect.ValueOf(list).Elem()

        if listVal.Kind() == reflect.Slice {

             for i:=0; i<listVal.Len(); i++ {
                 valueReflect := listVal.Index(i).Interface()
                 objValueFinal, ok := valueReflect.(HasCustomField)

                 if ok {
                    fmt.Println("OK")
                } else {
                    fmt.Println("NAO OK")
                }
        }
}

结果始终为“不正确”,我无法进行转换,我也尝试了其他几种方法,包括通过反射调用方法GetCustomField(),但未成功。

1 个答案:

答案 0 :(得分:0)

GetCustomField方法位于指针接收器*People上,但是分片包含People值。获取slice元素的地址以使用指针接收器:

valueReflect := listVal.Index(i).Addr().Interface()  // <-- Addr()

Run it on the playground

奖金简化:使用slice参数而不是指向slice的指针。

ProcessCustomField(users) // <-- do not take addr here
...

listVal := reflect.ValueOf(list) <-- do not call Elem() here

Run it on the playground