gpt4 book ai didi

go - 用反射遍历结构,用反射创建新的指针类型 slice

转载 作者:行者123 更新时间:2023-12-01 22:08:11 25 4
gpt4 key购买 nike

上下文:我正在尝试获取任何struct,并用随机数据填充它。

目前,我的最大障碍是,如果struct的字段是带有指针类型的 slice (即[]*Foo),我将无法弄清楚如何使用反射为该结构创建数据。

这是我的函数当前的样子:

func randFill(in interface{}) interface{} {
t := reflect.TypeOf(in)
v := reflect.ValueOf(in)

if v.Kind() == reflect.Ptr {
v = v.Elem()
}

switch v.Kind() {
case reflect.Struct:
newStr := reflect.New(t).Elem()
for i := 0; i < t.NumField(); i++ {
newV := randFill(reflect.New(t.Field(i).Type).Interface())
newStr.Field(i).Set(reflect.ValueOf(newV))
}

return newStr.Interface()
case reflect.Slice:
num := rand.Intn(10)
slice := reflect.MakeSlice(v.Type(), num, num)

for j := 0; j < num; j++ {
newC := slice.Index(j)
if newC.Kind() == reflect.Ptr {
ncInt := reflect.New(newC.Type())
newC = ncInt.Elem()
}
gen := randFill(newC.Interface())
slice.Index(j).Set(reflect.ValueOf(gen))
}

return slice.Interface()
//
// ... there are other cases down here for handling primitives
//
}

return nil
}

这在没有指针类型的 slice 上效果很好,但是下面是一些结构有问题的示例:

type Parent struct {
Name string
Age int
Children []*Child
}

type Child struct {
Name string
Age int
}

如果我创建了 Parent{}并将其传递给 randFill(Parent{}),那么在生成 *Child的值时会遇到麻烦,因为到达此行时:

newC := slice.Index(j)

此时,当处理 newC的片段时, []*Child的值为 (*Child)(nil),它是 reflect.Value类型。

newC := slice.Index(j)
fmt.Printf("%#v, %T", newC, newC) // Outputs: (*Child)(nil), reflect.Value

我无法从 reflect.Value初始化指针类型,或者我创建了不正确的slice类型,这就是问题的根源吗?

最佳答案

当您发现放置元素是一个指针时,您必须创建该指针指向的类型的实例,但是您正在创建一个新的指针。试试这个:

if newC.Kind() == reflect.Ptr {
ncInt := reflect.New(newC.Type().Elem())
newC = ncInt.Elem()
}

关于go - 用反射遍历结构,用反射创建新的指针类型 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59696300/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com