无法在使用反射创建的切片上使用 range,然后传递给 json.Unmarshal。

huangapple go评论81阅读模式
英文:

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)) //与t具有相同的类型
    fmt.Println(*typedSlice)                // invalid indirect of copy (type interface {})

    for _, l := range typedSlice {          //无法对copy (type interface {})进行迭代
        ret = append(ret, &l)
    }

    return ret
}

我创建了一个Go Playground,其中包含可工作的代码以帮助解决问题。

为什么这个切片似乎打印出一种类型,但编译时却是另一种类型?

英文:

I am getting the following errors from the code below:

>invalid indirect of typedSlice (type interface {})
>
>cannot range over typedSlice (type interface {})

This is confusing to me because reflect.TypeOf(copy) matches the type of 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
}

I've created a go playground with working code to help.

Why does it appear that this slice prints one type but compiles as another?

答案1

得分: 4

> invalid indirect of typedSlice (type interface {})

你无法对 typedSlice 进行间接引用,因为它是一个 interface{} 类型。你需要使用类型断言来提取指针。

realSlice := *typedSlice.(*[]Demo)

> cannot range over typedSlice (type interface {})

同样,由于 typedSlice 是一个 interface{} 类型,你无法对其进行范围遍历。如果你想要遍历其中的值,你需要使用类型断言,或者通过反射手动迭代:

for i := 0; i < o.Elem().Len(); i++ {
    ret = append(ret, o.Elem().Index(i).Interface())
}
英文:

> invalid indirect of typedSlice (type interface {})

You can't dereference typedSlice, because it's an interface{}. You would have to extract the pointer with a type assertion

realSlice := *typedSlice.(*[]Demo)

> cannot range over typedSlice (type interface {})

Again, since typedSlice is an interface{}, you can't range over it. If you want to range over the values you need to use a type assertion, or iterate manually via reflect:

for i := 0; i &lt; o.Elem().Len(); i++ {
	ret = append(ret, o.Elem().Index(i).Interface())
}

huangapple
  • 本文由 发表于 2015年12月9日 02:21:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/34163174.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定