当前位置: 首页 > 面试题库 >

通过Go中的反射为结构成员分配值

白星海
2023-03-14
问题内容

我有一个带有成员A,B,C字符串的struct v。使用反射,我可以获取字段名称及其值:

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"

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

在实践中,我试图将来自a的值分配给map[string]string结构中的相应字段,其中结构和映射定义可能会随着时间的变化而扩展,并且映射可能包含比该结构更多或更少的值。我已经考虑过使用JSON进行此操作,但是这种方法让我有些不高兴,因为使用反射来“几乎”到达那里是多么容易!

谢谢,肯


问题答案:

是的,有可能。

介绍

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

但你不希望修改地址/指针,但 尖锐的 价值,所以你必须从“导航”
Value的指针的Value尖头变量(结构),这是什么Value.Elem()是。看起来像这样:reflect.ValueOf(&s).Elem()

您可以使用方法获得Valuestruct字段的Value.FieldByName(),因为我们传递了指向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语言中反射的基础知识:

反射定律



 类似资料:
  • 反射值对象(reflect.Value)提供对结构体访问的方法,通过这些方法可以完成对结构体任意值的访问,如下表所示。 反射值对象的成员访问方法 方  法 备  注 Field(i int) Value 根据索引,返回索引对应的结构体成员字段的反射值对象。当值不是结构体或索引超界时发生宕机 NumField() int 返回结构体成员字段数量。当值不是结构体或索引超界时发生宕机 FieldByNa

  • 主要内容:结构体字段类型,获取成员反射信息任意值通过 reflect.TypeOf() 获得反射对象信息后,如果它的类型是结构体,可以通过反射值对象(reflect.Type)的 NumField() 和 Field() 方法获得结构体成员的详细信息。与成员获取相关的 reflect.Type 的方法如下表所示。 结构体成员访问的方法列表 方法 说明 Field(i int) StructField 根据索引,返回索引对应的结构体字段的信

  • 通过下列任意一个方法访问成员变量时将返回 Field 类型的对象或数组。 getFields() getField(String name) getDeclaredFields() getDeclaredField(String name) 上述方法返回的 Field 对象代表一个成员变量。例如,要访问一个名称为 price 的成员变量,示例代码如下: Field 类的常用方法如表 1 所示 表1

  • 我读了一大堆这么多的问题,但我似乎找不到答案。 我有以下课程: 在其他地方,我试图访问这些字符串: 为什么我会得到一个IllegalAccess异常?如果我删除field.get行,我可以在LogCat中看到以下行: 参考资料: 使用反射在Java中获取成员变量值的陷阱 反射:通过反射加载的类中的常量变量 通过反射访问Java静态最终ivar值

  • 在这两个示例中,通过偏移其他成员的指针来访问结构成员是否会导致未定义/未指定/实现定义的行为? C11§6.7.2.1第14段似乎表明,这应该是实施定义: 结构或联合对象的每个非位字段成员都以适合其类型的实现定义方式对齐。 后来又说: 结构对象中可能有未命名的填充,但在其开头没有。 但是,如下所示的代码似乎相当常见: 该标准似乎保证 与 和< code >( 原始应用程序正在考虑从一个结构字段到另

  • 本文向大家介绍go语言通过反射获取和设置结构体字段值的方法,包括了go语言通过反射获取和设置结构体字段值的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了go语言通过反射获取和设置结构体字段值的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的go语言程序设计有所帮助。