reflect.Set slice-of-structs value to a struct, without type assertion (because it's unknown)

吃可爱长大的小学妹 提交于 2019-12-25 08:08:44

问题


I'm creating a helper package to pop payloads from a queue. It's essential that this helper be agnostic to the struct used by the application importing it.

This (no-op, just example) function will provide a single payload from the queue, of the provided type like interface{}:

func One(like interface{}) interface{} {
    typ := reflect.TypeOf(like)
    one := reflect.New(typ)

    return one.Interface()
}

This function provides many payloads:

func Many(num int, like interface{}) interface{} {
    typ := reflect.TypeOf(like)
    many := reflect.MakeSlice(reflect.SliceOf(typ), num, num)

    for i := 0; i < num; i++ {
        one := One(typ)
        many.Index(i).Set(one)
    }

    return many.Interface()
}

An example of usage is:

type Payload struct {
    Id int
    Text string
}

func main() {
    Many(4, Payload{})
}

However, the above results in:

panic: reflect.Set: value of type **reflect.rtype is not assignable to type main.Payload

https://play.golang.org/p/ud23ZlD3Bx


回答1:


You're calling reflect.TypeOf on a reflect.Value, which is where **reflect.rtype is coming from.

Call your One function wth the like value directly, and assign that result to the slice.

func One(like interface{}) interface{} {
    typ := reflect.TypeOf(like)
    one := reflect.New(typ)

    return one.Interface()
}

func Many(num int, like interface{}) interface{} {
    typ := reflect.TypeOf(like)
    many := reflect.MakeSlice(reflect.SliceOf(typ), num, num)

    for i := 0; i < num; i++ {
        one := One(like)
        many.Index(i).Set(reflect.ValueOf(one).Elem())
    }

    return many.Interface()
}

https://play.golang.org/p/fHF_zrymcI



来源:https://stackoverflow.com/questions/40474682/reflect-set-slice-of-structs-value-to-a-struct-without-type-assertion-because

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!