在Go语言开发中,reflect包是实现运行时反射的核心工具。当我们需要序列化、校验或者ORM映射时,常常要在程序运行期间读取结构体的字段名称。如果处理方式不对,就可能拿到空字符串、标签名而非真实字段名,甚至引发panic。

使用reflect.Type获取字段名
最基础的方式是通过reflect.TypeOf拿到类型信息,再调用NumField和Field方法遍历。Field返回的StructField结构中,Name属性才是结构体的真实字段名称。
package main
import (
"fmt"
"reflect"
)
type User struct {
ID int
Name string
Age int
}
func main() {
u := User{ID: 1, Name: "Tom", Age: 20}
t := reflect.TypeOf(u)
// 遍历所有字段并打印名称
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
fmt.Println("字段名称:", field.Name)
}
}
通过FieldByName获取指定字段
如果只关心某个字段,可以使用Type或Value的FieldByName方法。它返回对应的StructField以及是否存在的布尔值,避免越界访问。
package main
import (
"fmt"
"reflect"
)
type User struct {
ID int
Name string
}
func main() {
u := User{ID: 2, Name: "Lucy"}
v := reflect.ValueOf(u)
field, ok := v.Type().FieldByName("Name")
if ok {
fmt.Println("找到字段:", field.Name)
} else {
fmt.Println("字段不存在")
}
}
处理指针与匿名字段
当传入的是指针时,需先用Elem方法取得指向的值类型。对于匿名字段,其Name与类型名相同,可通过Anonymous属性判断。
package main
import (
"fmt"
"reflect"
)
type Base struct {
CreatedAt string
}
type Account struct {
Base
Email string
}
func main() {
a := Account{Email: "test@ipipp.com"}
t := reflect.TypeOf(a)
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
fmt.Printf("名称:%s 匿名:%vn", f.Name, f.Anonymous)
}
}
常见错误与建议
- 对指针类型直接调用Field会导致panic,务必先Elem。
- 不要将结构体标签(tag)误认为字段名,标签应通过Tag.Get读取。
- 修改字段值时应使用CanSet判断,否则会panic。
掌握上述方式后,使用Go语言reflect包获取结构体字段名称就会变得清晰可靠,也能减少运行期错误。
Goreflectstruct_field修改时间:2026-07-30 22:30:17