通过反射创建结构实例并设置值

我想做什么

我尝试将instancea 的一个struct- 包括json tags 传递给 a func,创建一个新的instance,并在此之后设置value我field

尝试序列化(JSON),但值为空


注意:我在 SO 上查找了大量关于通过反射设置值的文章,但似乎我错过了一些细节

结构定义

这部分定义了带有 json 和 xml 标签的结构


type Person struct {

    Name string `json:"Name" xml:"Person>FullName"`

    Age  int    `json:"Age" xml:"Person>Age"`

}

创建实例(+包装成空接口)

之后我创建了一个实例并将其存储在一个interface{}- 为什么?因为在我的生产代码中,这些东西将在func接受 ainterface{}


var iFace interface{} = Person{

        Name: "Test",

        Age:  666,

    }

通过反射创建结构的新实例并设置值

iFaceType := reflect.TypeOf(iFace)

    item := reflect.New(iFaceType)

    s := item.Elem()

    if s.Kind() == reflect.Struct {

        fName := s.FieldByName("Name")

        if fName.IsValid() {

            // A Value can be changed only if it is

            // addressable and was not obtained by

            // the use of unexported struct fields.

            if fName.CanSet() {

                // change value of N

                switch fName.Kind() {

                case reflect.String:

                    fName.SetString("reflectedNameValue")

                    fmt.Println("Name was set to reflectedNameValue")

                }

            }

        }

        fAge := s.FieldByName("Age")

        if fAge.IsValid() {

            // A Value can be changed only if it is

            // addressable and was not obtained by

            // the use of unexported struct fields.

            if fAge.CanSet() {

                // change value of N

                switch fAge.Kind() {

                case reflect.Int:

                    x := int64(42)

                    if !fAge.OverflowInt(x) {

                        fAge.SetInt(x)

                        fmt.Println("Age was set to", x)

                    }

                }

            }

        }

    }

问题

我究竟做错了什么?

在生产代码中,我用数据填充多个副本并将其添加到slice...但这只有在s 保持在适当位置并且东西以相同的方式序列化

时才有意义。json tag


沧海一幻觉
浏览 80回答 1
1回答

蝴蝶不菲

你item的类型是reflect.Value. 您必须调用Value.Interface()以获取包含在其中的值:fmt.Println("reflected: \n" + JSONify(item.Interface()))通过此更改,输出将是(在Go Playground上尝试):normal: {    "Name": "Test",    "Age": 666}Name was set to reflectedNameValueAge was set to 42reflected: {    "Name": "reflectedNameValue",    "Age": 42}reflect.Value本身也是一个结构,但显然试图封送它与封送Person结构值不同。reflect.Value不实现将包装的数据封送为 JSON。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go