type t struct { fi int; fs string } var r t = t{ 123,"jblow" } var i64 int64 = 456
var field = reflect.TypeOf(r).Field(i).Name
>获取字段i的值为a)interface {},b)int – 这似乎工作
var iface interface {} = reflect.ValueOf(r).Field(i).Interface()
var i int = int(reflect.ValueOf(r).Field(i).Int())
>字段i的设置值 – 尝试一个 – panic
reflect.ValueOf(r).Field(i).SetInt(i64)
panic:reflect.Value·SetInt使用未导出字段获得的值
假设它不喜欢字段名“id”和“name”,因此重命名为“Id”和“Name”
a)这个假设是正确的吗?
b)如果正确,认为没有必要,因为在同一个文件/包
>设置字段i的值 – 尝试两个(字段名称大写) – panic
reflect.ValueOf(r).Field(i).SetInt(465)
reflect.ValueOf(r).Field(i).SetInt(i64)
panic:reflect.Value·SetInt使用不可解析的值
下面的@peterSO的说明是彻底和高质量
四。这个工作:
reflect.ValueOf(& r).Elem()。Field(i).SetInt(i64)
他还记录字段名称必须是可导出的(以大写字母开头)
Go json包将编组和解组JSON从和到Go结构。
这里是一个分步示例,设置结构字段的值,同时小心避免错误。
func (v Value) CanAddr() bool
CanAddr returns true if the value’s
address can be obtained with Addr.
Such values are called addressable. A
value is addressable if it is an
element of a slice,an element of an
addressable array,a field of an
addressable struct,or the result of
dereferencing a pointer. If CanAddr
returns false,calling Addr will
panic.
Go reflect
软件包有一个CanSet
函数,如果为真,意味着CanAddr也是true。
func (v Value) CanSet() bool
CanSet returns true if the value of v
can be changed. A Value can be changed
only if it is addressable and was not
obtained by the use of unexported
struct fields. If CanSet returns
false,calling Set or any
type-specific setter (e.g.,SetBool,
SetInt64) will panic.
我们需要确保我们可以设置struct字段。例如,
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) }