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

在 Go 语言中,结构体(struct)本身不自带运行时反射获取字段名和值的能力,但可以通过 reflect 包实现。核心思路是:将结构体实例转为 reflect.Value 和 reflect.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"})立即学习“go语言免费学习笔记(深入)”;
注意字段可访问性与标签(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())









