为了账号安全,请及时绑定邮箱和手机立即绑定

使用反射和动态类型附加到 go lang 切片

使用反射和动态类型附加到 go lang 切片

Go
千万里不及你 2022-06-27 09:35:50
,有一个给定的结构(Foo)。我发现这个概念很有趣,并且想知道对于动态类型也可以这样做。给定以下动态结构(完美运行),您如何创建切片并附加到它?在这里查看我的尝试:在这个片段中,我创建了动态类型。这工作正常。        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(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
查看完整描述

2 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

值为structTypea reflect.Type。该表达式reflect.TypeOf(structType)计算reflect.Typefor 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)

在 Go 操场上运行它。


这是代码的简化版本:


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)


查看完整回答
反对 回复 2022-06-27
?
SMILET

TA贡献1796条经验 获得超4个赞

如您所知,reflect.TypeOf返回传递给它的值的类型的reflect.Type表示。因此,如果您有一个值,例如,其类型为并且您将其传递给,则返回的将是该值所表示的类型的表示,而不是该类型的表示。structType reflect.Typereflect.TypeOfreflect.Typereflect.TypestructType


把事情简单化。


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

slice = reflect.Append(slice, v.Elem())

slice = reflect.Append(slice, v2.Elem())

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


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 165 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号