【问题标题】:Assigning a value to struct member through reflection in Go通过 Go 中的反射为结构成员赋值
【发布时间】:2015-03-22 20:11:04
【问题描述】:

我有一个结构体 v,其中包含成员 A、B、C 字符串。使用反射,我可以获得字段的名称及其值:

typ := v.Type()
for i := 0; i < v.NumField(); i++ {
    // gets us a StructField
    fi := typ.Field(i)
    fieldname := fi.Name
    fmt.Println(fieldname)
    val := fmt.Sprintf("%v", v.Field(i).Interface())
 }

既然我有名字,并且可以将值 OUT,我可以为字段分配新值吗?我想基本上做:

v.Field(fieldname).Interface() = "new value"

但这显然行不通。如果只知道字段的名称,是否可以将值分配给结构?

在实践中,我试图将 map[string]string 中的值分配给结构中的相应字段,其中结构和映射定义可能会随着时间的推移而扩展变化,并且映射可能包含更多或更少的值结构。我考虑过用 JSON 来做,但这种方法让我有点冷,看到使用反射“几乎”在那里是多么容易!

谢谢, 肯

【问题讨论】:

    标签: dictionary reflection struct go


    【解决方案1】:

    是的,有可能。

    简介

    由于要访问和修改变量(或字段)的值,因此需要使用reflect.Value 类型而不是reflect.Type。您可以通过reflect.ValueOf() 获取它。另外,为了通过反射修改它,您需要传递struct 的地址(指针)或您要修改的值(否则您只能读取它而不能修改它)。

    但是你不想修改地址/指针而是pointed值,所以你必须从指针的Value“导航”到指向的Value变量(结构),这就是Value.Elem() 的用途。它看起来像这样:reflect.ValueOf(&amp;s).Elem()

    您可以使用Value.FieldByName() 方法获取结构字段的Value,因为我们将指针的地址传递给ValueOf() 函数将是可设置的

    守则

    代码比介绍简单多了,看懂了。你也可以在Go Playground上试试:

    var s struct {
        A, B, C string
    }
    s.A, s.B, s.C = "a1", "b2", "c3"
    
    fmt.Println("Before:  ", s)
    
    v := reflect.ValueOf(&s).Elem()
    
    v.FieldByName("A").SetString("2a")
    v.FieldByName("B").SetString("2b")
    v.FieldByName("C").SetString("2c")
    
    fmt.Println("After:   ", s)
    
    // Using a map:
    m := map[string]string{"A": "ma", "B": "mb", "C": "mc"}
    for mk, mv := range m {
        v.FieldByName(mk).SetString(mv)
    }
    
    fmt.Println("From Map:", s)
    

    输出:

    Before:   {a1 b2 c3}
    After:    {2a 2b 2c}
    From Map: {ma mb mc}
    

    我建议阅读这篇博文以了解 Go 中反射的基础知识:

    The Laws of Reflection

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 2021-05-19
      • 2016-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多