使用reflection,你如何设置一个struct字段的值?
有一个艰难的时间使用reflect包使用struct字段。 特别是还没有想出如何设置字段值。 
键入t struct {fi int;  fs string}
 var rt = t {123,“jblow”}
 var i64 int64 = 456
- 
得到领域的名字我 – 这似乎工作 var field = reflect.TypeOf(r).Field(i).Name
- 
获得领域我的价值作为一个)interface {},b)int – 这似乎工作 var iface interface{} = reflect.ValueOf(r).Field(i).Interface()var i int = int(reflect.ValueOf(r).Field(i).Int())
- 
设置领域的价值 – 尝试一个恐慌 reflect.ValueOf(r).Field(i).SetInt( i64 )恐慌 :reflect.Value·SetInt使用取得的值使用未导出的字段 假设它不喜欢字段名称“id”和“name”,所以改名为“Id”和“Name” a)这个假设是否正确? b)如果正确,认为没有必要,因为在相同的文件/包 
- 
设置字段i的值 – 尝试两个(字段名称大写) – 恐慌 reflect.ValueOf(r).Field(i).SetInt( 465 )reflect.ValueOf(r).Field(i).SetInt( i64 )恐慌 :reflect.Value·SetInt使用unaddressable值 
以下说明@peterSO是彻底的,高质量
四。 这工作:
 reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 ) 
他还logging了域名必须是可导出的(以大写字母开头)
Go以开源代码的forms提供 。 了解反思的一个好方法是看看核心Go开发人员如何使用它。 例如,Go fmt和json软件包。 软件包文档包含指向软件包文件标题下的源代码文件的链接。
Go json包封送和解组JSON来自Go结构。
 这是一个循序渐进的例子,它可以设置一个struct字段的值,同时小心避免错误。 
  Go reflect包有一个CanAddr函数。 
 func (v Value) CanAddr() bool 
如果可以使用Addr获取值的地址,则CanAddr返回true。 这些值被称为可寻址的。 如果值是切片的元素,可寻址数组的元素,可寻址结构的字段或解引用指针的结果,则该值是可寻址的。 如果CanAddr返回false,调用Addr将会发生混乱。
  Go reflect包有一个CanSet函数,如果为true ,则暗示CanAddr也是true 。 
 func (v Value) CanSet() bool 
如果v的值可以改变,CanSet返回true。 值只有在可寻址的情况下才能被改变,并且不能通过使用未导出的结构字段来获得。 如果CanSet返回false,则调用Set或任何types特定的setter(例如,SetBool,SetInt64)将会发生混乱。
 我们需要确保我们可以Set struct字段。 例如, 
 package main import ( "fmt" "reflect" ) func main() { type t struct { N int } var n = t{42} // N at start fmt.Println(nN) // 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(nN) } Output: 42 7 
如果我们可以确定所有的错误检查是不必要的,那么这个例子简化为:
 package main import ( "fmt" "reflect" ) func main() { type t struct { N int } var n = t{42} fmt.Println(nN) reflect.ValueOf(&n).Elem().FieldByName("N").SetInt(7) fmt.Println(nN) } 
这似乎工作:
 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