不能在用反射制作的切片上使用范围,然后通过 json.Unmarshal

Can't use range on slice made with reflect then passed json.Unmarshal

我从下面的代码中得到以下错误:

invalid indirect of typedSlice (type interface {})

cannot range over typedSlice (type interface {})

这让我感到困惑,因为 reflect.TypeOf(copy) 匹配 t 的类型。

func Unmarshal(t reflect.Type) []interface{} {

    ret := []interface{}{}
    s := `[{"Name":"The quick..."}]`

    slice := reflect.Zero(reflect.SliceOf(t))
    o := reflect.New(slice.Type())
    o.Elem().Set(slice)
    typedSlice := o.Interface()

    json.Unmarshal([]byte(s), typedSlice)

    fmt.Println(typedSlice)                 // &[{The quick...}]
    fmt.Println(reflect.TypeOf(typedSlice)) //same type as t
    fmt.Println(*typedSlice)                // invalid indirect of copy (type interface {})

    for _, l := range typedSlice {          //cannot range over copy (type interface {})
        ret = append(ret, &l)
    }

    return ret
}

我创建了一个 go playground 工作代码来提供帮助。

为什么这个切片打印出一种类型但编译成另一种类型?

invalid indirect of typedSlice (type interface {})

您不能取消引用 typedSlice,因为它是一个 interface{}。您必须使用类型断言

提取指针
realSlice := *typedSlice.(*[]Demo)

cannot range over typedSlice (type interface {})

同样,由于 typedSlice 是一个 interface{},您不能对其进行范围调整。如果你想遍历需要使用类型断言的值,或者通过 reflect:

手动迭代
for i := 0; i < o.Elem().Len(); i++ {
    ret = append(ret, o.Elem().Index(i).Interface())
}