Go中interface{}需用reflect.TypeOf和reflect.ValueOf获取动态类型与值,注意nil检查、可寻址性及指针解引用;结构体仅导出字段可反射访问,.Interface()可转回interface{}再断言,但应避免强制转具体类型。
在 Go 中,interface{} 是空接口,能接收任意类型值。要获取其背后的具体类型和值,需借助 reflect 包。关键不是“类型断言”(那是编译期行为),而是运行时通过反射探查底层结构。
传入 interface{} 后,先用 reflect.TypeOf() 得到 reflect.Type,用 reflect.ValueOf() 得到 reflect.Value。注意:若原值为 nil 接口,Value 会是零值,需提前检查。
var x interface{} = "hello",reflect.TypeOf(x) 返回 string,不是 interface{}
.Addr() 前需确认 .CanAddr() 为 true;若原始变量是字面量或临时值(如函数返回值直接赋给 interface{}),则不可寻址interface{}(&v)),TypeOf 返回 *T,ValueOf 的 .Elem() 才能取到 T 的值常遇到传入的是值还是指针,影响后续字段访问。可用 .Kind()
判断基础类别,再决定是否 .Elem():
v.Kind() == reflect.Ptr 表示底层是指针,可调用 v.Elem() 获取指向的值(但需先 v.IsValid() && !v.IsNil())v.Kind() == reflect.Interface 表示该 interface{} 里又包了一个 interface{},需递归调用 v.Elem() 或 v.Interface() 再反射.Elem() 会 panic,务必先校验 Kind当 interface{} 持有 struct 时,常用反射遍历字段。但注意:只有导出字段(大写开头)才能被反射读取;私有字段无法访问,即使用 .CanInterface() 为 false 也无法绕过。
v.Kind() == reflect.Struct 确认是结构体,再用 v.NumField() 和 v.Field(i) 遍历v.Field(i) 返回一个 Value,可用 .Interface() 转回原始类型(前提是可导出且未被设为不可寻址)反射不能“强制转换”类型,但可通过 .Interface() 把 reflect.Value 转回 interface{},再配合类型断言得到具体类型变量:
val := v.Interface() 得到 interface{},然后 if s, ok := val.(string) { ... }
reflect.Type.Kind() 和 reflect.Type.Name() 做分支判断,避免大量断言