首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Reflect,如何设置struct字段的值?

使用Reflect,如何设置struct字段的值?
EN

Stack Overflow用户
提问于 2018-05-09 00:46:18
回答 2查看 0关注 0票数 0

有一段艰难的时间使用reflect包使用struct字段。特别是还没有想出如何设置字段值。

代码语言:javascript
复制
键入t struct {fi int; fs字符串}
var rt = t {123,“jblow”}
是i64 int64 = 456
  1. 得到领域的名字 var field = reflect.TypeOf(r).Field(i).Name
  2. 获得领域我的价值作为)界面{} var iface interface{} = reflect.ValueOf(r).Field(i).Interface() var i int = int(reflect.ValueOf(r).Field(i).Int())
  3. 设定场的价值 reflect.ValueOf(r).Field(i).SetInt( i64 ) panic:reflect.Value·SetInt,使用取得的值使用未导出的字段 假设它不喜欢字段名称“id”和“name”,所以更名为“Id”和“Name” a)这个假设是否正确? b)如果正确,认为没有必要,因为在相同的文件/包
  4. 设置字段i的值 - 尝试两个(字段名称大写) reflect.ValueOf(r).Field(i).SetInt( 465 ) reflect.ValueOf(r).Field(i).SetInt( i64 ) 恐慌:reflect.Value·SetInt使用不可寻址的值

以下由@peterSO说明是彻底的和高质量的

reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 )

EN

回答 2

Stack Overflow用户

发布于 2018-05-09 09:30:54

包文档具有指向标题包文件下的源代码文件的链接。

Go JSON包、封送和解组将JSON从Go结构发送到Go结构。

下面是一个逐步设置struct字段,同时小心避免错误。

代码语言:txt
复制
func (v Value) CanAddr() bool

如果可以使用addr获得值的地址,则CanAddr返回true。这些值称为可寻址。如果值是片的元素、可寻址数组的元素、可寻址结构的字段或取消引用指针的结果,则值是可寻址的。如果CanAddr返回false,调用addr将引起恐慌。

如果true,意味着CanAddr也是true

代码语言:txt
复制
func (v Value) CanSet() bool

如果v的值可以更改,则CanSet返回true。只有当一个值是可寻址的,并且不是通过使用未导出的struct字段获得时,它才能被更改。如果CanSet返回false,调用set或任何特定类型的setter(例如,SetBool,SetInt 64)将引起恐慌。

例如,

代码语言:txt
复制
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

如果我们可以确定所有错误检查都是不必要的,则示例简化为,

代码语言:txt
复制
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)
}
票数 0
EN

Stack Overflow用户

发布于 2018-05-09 09:52:03

这似乎是可行的:

代码语言:txt
复制
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()))
}

印刷品:

代码语言:txt
复制
123
321
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100008423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档