

新闻资讯
技术学院在 Go 中,用 reflect.Indirect 配合 reflect.ValueOf 可安全获取指针指向的实际类型,它递归解引用多级指针或接口,返回非指针非接口的 reflect.Value,再调用 .Type() 得到底层类型;对非指针值原样返回,nil 指针返回无效 Value 需检查。
在 Go 中,获取指针指向的**实际类型**(而非指针类型本身),常用 reflect.Indirect 配合 reflect.TypeOf 或 reflect.ValueOf。关键在于:指针可能多层嵌套(如 **int),Indirect 会递归解引用直到得到非指针值,返回其 reflect.Type 或 reflect.Value。
reflect.Indirect 接收一个 reflect.Value,若该值是接口或指针类型,它会持续解引用,直到得到一个非指针、非接口的值(或 nil)。之后可调用 .Type() 得到最终类型。
reflect.TypeOf(v) 返回的是 *T 类型;要得到 T,需先转为 Value 再 Indirect
reflect.Indirect 对非指针值(如 int、struct 值)会原样返回,安全可用Indirect 返回零值 reflect.Value(.Is
Valid() == false),需检查以下代码演示如何从任意指针(包括多级)安全提取底层类型名:
func getUnderlyingType(v interface{}) string {
val := reflect.ValueOf(v)
if !val.IsValid() {
return "invalid"
}
indirectVal := reflect.Indirect(val)
if !indirectVal.IsValid() {
return "nil pointer"
}
return indirectVal.Type().String()
}
// 使用
var i int = 42
p := &i
pp := &p
fmt.Println(getUnderlyingType(p)) // "int"
fmt.Println(getUnderlyingType(pp)) // "int"
fmt.Println(getUnderlyingType(42)) // "int"(非指针也兼容)
reflect.TypeOf 只做静态类型检查,不处理运行时解引用;reflect.Indirect 是运行时操作,依赖 reflect.Value。
reflect.TypeOf(&i) → *int
reflect.Indirect(reflect.ValueOf(&i)).Type() → int
reflect.ValueOf(x) 后接 Indirect 最稳妥实际使用中容易忽略这些细节:
Indirect 不改变原始变量,只返回新 Value;如需修改原指针指向的值,要用 .Addr().Interface() 或 .Set* 方法Indirect 能拿到类型,但无法读写字段(反射权限限制)interface{})传入后,ValueOf 得到的是接口内部存储的值,Indirect 会对其内部值解引用(如果它是指针)