英文:
reflect.Set slice-of-structs value to a struct, without type assertion (because it's unknown)
问题
我正在创建一个辅助包,用于从队列中弹出有效载荷。这个辅助包对导入它的应用程序使用的结构类型是不可知的,这一点非常重要。
下面是一个示例函数(无操作),它将从队列中提供一个指定类型的有效载荷,类型为interface{}
:
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(typ)
many.Index(i).Set(one)
}
return many.Interface()
}
以下是用法示例:
type Payload struct {
Id int
Text string
}
func main() {
Many(4, Payload{})
}
然而,上述代码会导致以下错误:
panic: reflect.Set: value of type **reflect.rtype is not assignable to type main.Payload
你可以在这里查看完整的示例代码:https://play.golang.org/p/ud23ZlD3Bx
英文:
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
答案1
得分: 2
你正在对reflect.Value
调用reflect.TypeOf
,这就是**reflect.rtype
的来源。
直接使用like
值调用你的One
函数,并将结果赋给切片。
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
英文:
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()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论