如何在Golang中获取字段名称和值_遍历结构体获取信息

Go中结构体需用reflect包配合指针才能反射获取字段名和值;必须传入结构体指针,调用Elem()获取值和类型,再遍历字段。

在 Go 语言中,结构体(struct)本身不自带运行时反射获取字段名和值的能力,但可以通过 reflect 包实现。核心思路是:将结构体实例转为 reflect.Valuereflect.Type,再遍历其字段并提取名称与对应值。

使用 reflect 遍历结构体字段

必须传入结构体的指针(&structVar),否则 reflect.ValueOf() 得到的是不可寻址的副本,无法读取未导出字段(小写开头字段),且部分操作会 panic。

  • 调用 reflect.ValueOf(v).Elem() 获取实际值(前提是 v 是指针)
  • reflect.TypeOf(v).Elem() 获取结构体类型信息
  • 通过 .NumField().Field(i) / .FieldByName(name) 访问字段

获取字段名和值的完整示例

以下函数接收任意结构体指针,打印每个导出字段的名称和值:

func printStructFields(v interface{}) {
    val := reflect.ValueOf(v)
    if val.Kind() != reflect.Ptr || val.IsNil() {
        panic("expect non-nil struct pointer")
    }
    val = val.Elem()
    typ := val.Type()

    for i := 0; i < val.NumField(); i++ {
        field := typ.Field(i)
        value := val.Field(i)

        // 只处理导出字段(首字母大写)
        if !field.IsExported() {
            continue
        }

        fmt.Printf("Field: %s, Type: %s, Value: %v\n", 
            field.Name, field.Type, value.Interface())
    }
}

调用方式:printStructFields(&MyStruct{A: 123, B: "hello"})

注意字段可访问性与标签(tag)

Go 中只有导出字段(首字母大写)才能被 reflect 读取值。非导出字段会返回零值或 panic(取决于操作)。若需映射 JSON、数据库列等,常借助 struct tag:

  • 定义:Name string `json:"name" db:"user_name"`
  • 读取:field.Tag.Get("json")field.Tag.Get("db")
  • tag 值不影响字段值读取,仅提供元信息

安全获取字段值(避免 panic)

对可能为 nil 的指针字段或接口字段,应检查有效性:

  • if !value.IsValid() { continue }
  • if value.CanInterface() { value.Interface() } —— 确保能安全转为 interface{}
  • 对指针字段,可用 value.Elem() 解引用(需先 value.Kind() == reflect.Ptr && !value.IsNil()