为何Golang反射对同值变量因初始化方式不同返回不同Kind?
Go反射中interface与slice类型判定差异问题
以下是测试代码:
// You can edit this code! // Click here and start typing. package main import ( "fmt" "reflect" ) type MyStruct struct{} func main() { m := make(map[string]any) m["key"] = make([]*MyStruct, 0) myStructs := m["key"] myStructsVal := reflect.ValueOf(&myStructs) fmt.Println(myStructsVal.Type().Kind()) fmt.Println(myStructsVal.Type().Elem().Kind()) nm := make(map[string][]*MyStruct) nm["key"] = make([]*MyStruct, 0) nmStructs := nm["key"] nmStructsVal := reflect.ValueOf(&nmStructs) fmt.Println(nmStructsVal.Type().Kind()) fmt.Println(nmStructsVal.Type().Elem().Kind()) }
运行输出:
ptr interface ptr slice
核心差异在于两个变量的静态类型不同:
- 第一个场景中,
m的类型是map[string]any,从map中取出的myStructs静态类型是any(即interface{}),尽管它存储的动态值是[]*MyStruct,但变量本身的类型是接口类型。当你取它的地址传给反射时,反射识别的是指向interface{}的指针,所以Elem().Kind()返回interface。 - 第二个场景中,
nm的类型是map[string][]*MyStruct,取出的nmStructs静态类型就是[]*MyStruct(具体的slice类型),取地址后反射识别为指向slice的指针,因此Elem().Kind()返回slice。
反射操作的是变量的静态编译类型,而非其存储的动态值类型,这是你之前忽略的关键点。
内容的提问来源于stack exchange,提问作者arl
相关产品推荐
相关产品推荐

