gpt4 book ai didi

go - 使用反射和动态类型附加去朗片

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

我的问题是对https://stackoverflow.com/a/54909356(操场:https://play.golang.org/p/vXOqTVSEleO)的跟进。
在该答案中,有一个给定的结构(Foo)。我发现这个概念很有趣,并且想知道对于动态类型也可以做到这一点。
给定以下动态结构(效果很好),如何创建 slice 并将其附加到 slice ?
在这里查看我的尝试:
在此代码段中,我创建了动态类型。这很好。


typeString := reflect.TypeOf("")
typeInteger := reflect.TypeOf(0)
fields := make(map[string]*reflect.StructField)
fields["A"] = &reflect.StructField{
Name: "A",
Type: typeString,
Tag: reflect.StructTag(`json:"a"`),
}
fields["B"] = &reflect.StructField{
Name: "B",
Type: typeInteger,
Tag: reflect.StructTag(`json:"b"`),
}
var structFields []reflect.StructField
for _, v := range fields {
structFields = append(structFields, *v)
}

structType := reflect.StructOf(structFields)
使用该结构,我们认为它可以正常工作:
        v := reflect.New(structType)
v.Elem().FieldByName("A").SetString("qwer")
v.Elem().FieldByName("B").SetInt(123)

v2 := reflect.New(structType)
v2.Elem().FieldByName("A").SetString("asdf")
v2.Elem().FieldByName("B").SetInt(456)

//+ these look good
fmt.Printf("%v\n", v)
fmt.Printf("%v\n", v2)
但是,进入动态 slice 时,会出现错误:
        reflection := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(structType).Elem()), 0, 0)

reflectionValue := reflect.New(reflection.Type())
reflectionValue.Elem().Set(reflection)

slicePtr := reflect.ValueOf(reflectionValue.Interface())

sliceValuePtr := slicePtr.Elem()

value := v.Elem()

// ERROR HERE
toSet := reflect.Append(sliceValuePtr, value)
需要进行哪些调整才能使所有内容与 Append对齐?
请在操场上查看以下内容:
https://play.golang.org/p/Vrx7FTlVBp9

最佳答案

structTypereflect.Type。表达式reflect.TypeOf(structType)reflect.Type评估为reflect.Type。直接使用structType而不是调用reflect.TypeOf(structType)

typeString := reflect.TypeOf("")
typeInteger := reflect.TypeOf(0)
fields := make(map[string]*reflect.StructField)
fields["A"] = &reflect.StructField{
Name: "A",
Type: typeString,
Tag: reflect.StructTag(`json:"a"`),
}
fields["B"] = &reflect.StructField{
Name: "B",
Type: typeInteger,
Tag: reflect.StructTag(`json:"b"`),
}
var structFields []reflect.StructField
for _, v := range fields {
structFields = append(structFields, *v)
}

structType := reflect.StructOf(structFields)

v := reflect.New(structType)
v.Elem().FieldByName("A").SetString("qwer")
v.Elem().FieldByName("B").SetInt(123)

v2 := reflect.New(structType)
v2.Elem().FieldByName("A").SetString("asdf")
v2.Elem().FieldByName("B").SetInt(456)

//+ these look good
fmt.Printf("%v\n", v)
fmt.Printf("%v\n", v2)

reflection := reflect.MakeSlice(reflect.SliceOf(structType), 0, 0)

fmt.Printf("typeof structType: %v\n", structType)
fmt.Printf("typeof structType | elem: %v\n", reflect.TypeOf(structType).Elem())

reflectionValue := reflect.New(reflection.Type())
reflectionValue.Elem().Set(reflection)

slicePtr := reflect.ValueOf(reflectionValue.Interface())

sliceValuePtr := slicePtr.Elem()

value := v.Elem()

fmt.Printf("value: %T = (%v)\n", value, value)
fmt.Printf("slice: %T = (%v)\n", sliceValuePtr, sliceValuePtr)

toSet := reflect.Append(sliceValuePtr, value)
fmt.Printf("toSet: %T = (%v)\n", toSet, toSet)

sliceValuePtr.Set(toSet)

result := sliceValuePtr.Interface()

fmt.Printf("result: %T = (%v)\n", result, result)
Run it on the Go playground
这是代码的简化版本:
stringType := reflect.TypeOf("")
intType := reflect.TypeOf(0)
t := reflect.StructOf([]reflect.StructField{
{
Name: "A",
Type: stringType,
Tag: reflect.StructTag(`json:"a"`),
},
{
Name: "B",
Type: intType,
Tag: reflect.StructTag(`json:"b"`),
},
})

v1 := reflect.New(t).Elem()
v1.FieldByName("A").SetString("qwer")
v1.FieldByName("B").SetInt(123)

v2 := reflect.New(t).Elem()
v2.FieldByName("A").SetString("asdf")
v2.FieldByName("B").SetInt(456)

slice := reflect.MakeSlice(reflect.SliceOf(t), 0, 0)
slice = reflect.Append(slice, v1, v2)
fmt.Printf("result: %s = (%v)\n", slice.Type(), slice)
Run it on the playground

关于go - 使用反射和动态类型附加去朗片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63495797/

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