Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
遍历Go中结构的字段_Go_Go Reflect - Fatal编程技术网

遍历Go中结构的字段

遍历Go中结构的字段,go,go-reflect,Go,Go Reflect,基本上,(据我所知)遍历struct字段值的唯一方法如下: type Example struct { a_number uint32 a_string string } //... r := &Example{(2 << 31) - 1, "...."}: for _, d:= range []interface{}{ r.a_number, r.a_string, } { //do something with the d } 类型示例结构{ a

基本上,(据我所知)遍历
struct
字段值的唯一方法如下:

type Example struct {
    a_number uint32
    a_string string
}

//...

r := &Example{(2 << 31) - 1, "...."}:
for _, d:= range []interface{}{ r.a_number, r.a_string, } {
  //do something with the d
}
类型示例结构{
a_编号uint32
一串
}
//...

r:=&Example{(2使用
field(i)
检索字段的
reflect.Value
后,可以获得 通过调用
interface()
从中获取接口值。然后,所述接口值表示 字段的值

没有将字段值转换为具体类型的函数, 您可能知道,go中没有泛型。因此,没有签名为
GetValue()T
T
是该字段的类型(当然会根据字段的不同而变化)

在go中可以实现的最接近的功能是
GetValue()接口{}
,这正是
reflect.Value.interface()
提议

下面的代码说明了如何获取结构中每个导出字段的值 使用反射():

导入(
“fmt”
“反映”
)
func main(){
x:=struct{Foo string;Bar int}{“Foo”,2}
v:=反射值(x)
值:=make([]接口{},v.NumField())
对于i:=0;i
如果您希望遍历结构的字段和值,则可以使用下面的Go代码作为参考

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Fname  string
    Lname  string
    City   string
    Mobile int64
}

func main() {
    s := Student{"Chetan", "Kumar", "Bangalore", 7777777777}
    v := reflect.ValueOf(s)
    typeOfS := v.Type()

    for i := 0; i< v.NumField(); i++ {
        fmt.Printf("Field: %s\tValue: %v\n", typeOfS.Field(i).Name, v.Field(i).Interface())
    }
}
主程序包
进口(
“fmt”
“反映”
)
类型学生结构{
Fname字符串
名称字符串
城市线
移动int64
}
func main(){
学生{“切坦”、“库马尔”、“班加罗尔”,7777}
v:=反射值
typeOfS:=v.Type()
对于i:=0;i
磨合

注意:如果未导出结构中的字段,则
v.Field(i).Interface()
将给出panic
panic:reflect.Value.Interface:无法返回从未报告的字段或方法获得的值。

获取解决方案,以防需要应用于
映射[string]int

主程序包
进口(
“fmt”
“反映”
)
类型BaseStats结构{
Hp int
HpMax int
Mp int
MpMax int
强度整数
速度整数
智力智力智力
}
类型Stats结构{
底图[string]int
修饰符[]字符串
}
func stats创建(stats BaseStats)stats{
s:=Stats{
Base:make(映射[string]int),
}
//遍历结构的字段
v:=反射值(统计)
typeOfS:=v.Type()
对于i:=0;i
可能太晚了:))但还有另一种解决方案,您可以找到structs的键和值,并对其进行迭代

package main

import (
    "fmt"
    "reflect"
)

type person struct {
    firsName string
    lastName string
    iceCream []string
}

func main() {
    u := struct {
        myMap    map[int]int
        mySlice  []string
        myPerson person
    }{
        myMap:   map[int]int{1: 10, 2: 20},
        mySlice: []string{"red", "green"},
        myPerson: person{
            firsName: "Esmaeil",
            lastName: "Abedi",
            iceCream: []string{"Vanilla", "chocolate"},
        },
    }
    v := reflect.ValueOf(u)
    for i := 0; i < v.NumField(); i++ {
        fmt.Println(v.Type().Field(i).Name)
        fmt.Println("\t", v.Field(i))
    }
}
Go 1.17(2021年第3季度)应添加一个新选项,通过和进行修复

反射:添加VisibleFields函数 当编写反映在结构类型上的代码时,通常需要知道完整的结构字段集,包括由于嵌入匿名成员而可用的字段,同时排除由于与另一个同名字段处于同一级别而被删除的字段

这样做的逻辑并不复杂,但有点微妙,很容易出错

此CL向reflect包添加一个新的
VisibleFields
函数,该函数返回应用于给定结构类型的完整有效字段集

字段:=可视字段(典型)
对于j,字段:=范围字段{
...
}

使用
reflect
包。首先,使用
reflect.TypeOf
获取变量的类型,并使用
reflect.NumField
获取元素的数量。要迭代获取结构字段的值,必须反映变量并使用函数
rg.Elem().Field(i)

主程序包
进口(
“fmt”
“反映”
)
类型Gopher结构{
名称字符串
色串
整年
}
func main(){
g:=地鼠{名称:“AAA”,颜色:“BBBB”,年份:2021}
gtype:=反射.TypeOf(g)
numFields:=gtype.NumField()
rg:=反射值(&g)
对于i:=0;i
使用以下方法:

type x struct {
    Id  int
    jsj int
}
func main() {
    x2 := x{jsj: 10, Id: 5}
    v := reflect.ValueOf(x2)
    for i := 0; i < v.NumField(); i++ {
        fmt.Println(v.Field(i))
    }
}
类型x结构{
Id int
jsj int
}
func main(){
x2:=x{jsj:10,Id:5}
v:=反射值(x2)
对于i:=0;i
=>10


=>5

这里有一篇关于反射的非常有趣的文章:下面是文章中的一个示例:但是请注意,您不能使用反射包查找未导出的字段(即以小写开头的字段)是的,因为go不需要泛型。Cough,Cough:-)有办法获取字段的类型吗?via,是的。但是请注意,类型不是go中的一级公民,因此只能使用
reflect
v.field(i.Interface()实例化该类型的新值
如果您试图访问未导出的私有字段,您会感到恐慌。请小心:)使用
v.Field(i).CanInterface()
如果出现未报告的字段,可以避免恐慌。如何获取字段名?这是一个很好的答案。这是我一直在寻找的答案。大家好,欢迎来到Stack Overflow!请接受。感谢您提供答案(问题的年龄无关紧要)。您能再解释一下您的答案是如何解决问题的吗?
and there is no *panic* for v.Field(i)
type x struct {
    Id  int
    jsj int
}
func main() {
    x2 := x{jsj: 10, Id: 5}
    v := reflect.ValueOf(x2)
    for i := 0; i < v.NumField(); i++ {
        fmt.Println(v.Field(i))
    }
}