使用reflect,如何设置结构字段的值?

| 在使用ѭ0with包处理结构字段时遇到了麻烦。特别是,还没有弄清楚如何设置字段值。 输入t struct {fi int; fs字符串} var r t = t {123,\“ jblow \”} var i64 int64 = 456 获取字段i的名称-这似乎起作用
var field = reflect.TypeOf(r).Field(i).Name
作为a)接口{},b)int获取字段i的值-这似乎有效
var iface interface{} = reflect.ValueOf(r).Field(i).Interface()
var i int = int(reflect.ValueOf(r).Field(i).Int())
设置字段i的值-尝试一次-紧急
reflect.ValueOf(r).Field(i).SetInt( i64 )
恐慌:使用通过未导出字段获得的值,reflect.Value·SetInt 假设它不喜欢字段名称\“ id \”和\“名称\”,因此重命名为\“ Id \”和\“名称\” a)这个假设正确吗? b)如果正确,则认为没有必要,因为在同一文件/包中 设置字段i的值-尝试两个(字段名大写)-紧急
reflect.ValueOf(r).Field(i).SetInt( 465 )
reflect.ValueOf(r).Field(i).SetInt( i64 )
恐慌:使用不可寻址的值反射。值·SetInt @peterSO的以下说明全面,高质量 四。这有效:
reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 )
他还证明字段名称必须是可导出的(以大写字母开头)     
已邀请:
        Go可以作为开源代码使用。了解反射的一个好方法是查看核心Go开发人员如何使用它。例如,Go fmt和json包。软件包文档在“软件包文件”标题下具有指向源代码文件的链接。 Go json程序包将JSON从Go结构中封送或取消封送JSON。 这是一个分步示例,该示例设置
struct
字段的值,同时小心避免错误。 Go
reflect
软件包具有
CanAddr
功能。
func (v Value) CanAddr() bool
  如果值的CanAddr返回true   地址可以通过Addr获取。   这样的值称为可寻址的。一种   如果值是可寻址的   切片的元素,   可寻址数组,一个   可寻址结构,或   取消引用指针。如果CanAddr   返回false,调用Addr将   恐慌。 Go
reflect
软件包具有
CanSet
函数,如果为
true
,则意味着
CanAddr
也是
true
func (v Value) CanSet() bool
  如果v的值,则CanSet返回true   可以更改。值可以更改   仅当它是可寻址的并且不是   通过使用未出口获得   结构字段。如果CanSet返回   假,调用Set或任何   特定类型的设置器(例如SetBool,   SetInt64)会惊慌。 我们需要确保可以在字段“ѭ8”中
Set
。例如,
package main

import (
    \"fmt\"
    \"reflect\"
)

func main() {
    type t struct {
        N int
    }
    var n = t{42}
    // N at start
    fmt.Println(n.N)
    // pointer to struct - addressable
    ps := reflect.ValueOf(&n)
    // struct
    s := ps.Elem()
    if s.Kind() == reflect.Struct {
        // exported field
        f := s.FieldByName(\"N\")
        if f.IsValid() {
            // A Value can be changed only if it is 
            // addressable and was not obtained by 
            // the use of unexported struct fields.
            if f.CanSet() {
                // change value of N
                if f.Kind() == reflect.Int {
                    x := int64(7)
                    if !f.OverflowInt(x) {
                        f.SetInt(x)
                    }
                }
            }
        }
    }
    // N at end
    fmt.Println(n.N)
}

Output:
42
7
如果可以确定所有错误检查都是不必要的,则该示例可以简化为:
package main

import (
    \"fmt\"
    \"reflect\"
)

func main() {
    type t struct {
        N int
    }
    var n = t{42}
    fmt.Println(n.N)
    reflect.ValueOf(&n).Elem().FieldByName(\"N\").SetInt(7)
    fmt.Println(n.N)
}
    
        这似乎可行:
package main

import (
    \"fmt\"
    \"reflect\"
)

type Foo struct {
    Number int
    Text string
}

func main() {
    foo := Foo{123, \"Hello\"}

    fmt.Println(int(reflect.ValueOf(foo).Field(0).Int()))

    reflect.ValueOf(&foo).Elem().Field(0).SetInt(321)

    fmt.Println(int(reflect.ValueOf(foo).Field(0).Int()))
}
印刷品:
123
321
    

要回复问题请先登录注册