应优先用 v.kind() 判断类型类别,而非 reflect.typeof(x) 比较 type 对象;结构体统一为 reflect.struct,指针需先 v.elem() 再操作字段;命名类型识别需结合 type.name() 和 pkgpath();调用方法时须匹配接收者类型且参数包装为 reflect.value。

用 v.Kind() 做分支,而不是 reflect.TypeOf(x) == reflect.TypeOf(MyStruct{})
直接比较 reflect.Type 对象几乎总是错的。比如你定义了 type User struct{ Name string },传入一个 User{},reflect.TypeOf(x) 返回的是 main.User;但如果你在另一个包里也定义了同名结构体,它的 Type 就是 otherpkg.User —— 两者 == 永远为 false。
真正该比的是底层类别:v.Kind() == reflect.Struct。它不关心包路径、名字,只认 Go 运行时的 27 种基础表示。所有结构体、无论是否导出、是否跨包,Kind() 都是 reflect.Struct。
- 判断是否为自定义结构体:
v.Kind() == reflect.Struct - 判断是否为指针指向结构体:
v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct - 判断是否为切片且元素是结构体:
v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Struct
传入结构体指针时,必须先 v.Elem() 才能访问字段
常见 panic:panic: reflect: call of reflect.Value.NumField on ptr Value。这是因为 reflect.ValueOf(&u) 得到的是 ptr 类型的 Value,而 NumField()、FieldByName() 等方法只对 struct 类型有效。
安全做法是统一解引用:
- 先检查:
if v.Kind() == reflect.Ptr { v = v.Elem() } - 再确认:
if v.Kind() != reflect.Struct { return } - 最后操作:
v.FieldByName("Name").Interface()
注意:如果传进来的是 nil 指针,v.Elem() 会 panic,所以实际使用前建议加 v.IsValid() && v.CanInterface() 判断。
区分命名类型和匿名类型:用 Type.Name() 而不是 Kind()
当你需要识别“是不是这个特定的自定义类型”,比如只处理 MyConfig 而非任意 struct,就得看 Type.Name() 和 Type.PkgPath()。
v.Kind() 告诉你是结构体,v.Type().Name() 才告诉你它叫什么名字(仅对命名类型非空);v.Type().PkgPath() 是包路径,用于避免重名冲突。
- 判断是否为当前包的
MyConfig:v.Kind() == reflect.Struct && v.Type().Name() == "MyConfig" && v.Type().PkgPath() == "your/package" - 匿名结构体(如
struct{ X int })的Name()返回空字符串,此时只能靠Kind()+ 字段特征(如v.NumField() == 1 && v.Field(0).Type().Name() == "int")粗略匹配
反射调用方法前,必须确保接收者匹配且方法导出
用 v.MethodByName("Save") 获取方法后,.Call() 失败往往不是因为名字错了,而是接收者类型不匹配。
- 值接收者方法(
func (u User) Save()):只能用值类型的reflect.Value调用,即reflect.ValueOf(u),不能用&u - 指针接收者方法(
func (u *User) Update()):可用值或指针调用,Go 会自动取地址 —— 但前提是原始值可寻址,即你传的是&u,而不是u - 私有方法(小写开头)无法被
MethodByName()找到,返回零值reflect.Value,调用.Call()会 panic
最容易被忽略的一点:反射调用方法时,参数必须是 []reflect.Value,每个参数都要包装成 reflect.ValueOf(arg),不能直接传原始 Go 值。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











