Go 获取未初始化切片的类型
我想返回一种类型的Go 获取未初始化切片的类型,go,reflection,slice,Go,Reflection,Slice,我想返回一种类型的接口{},而输入值可能是var m[]*MyModel 我已经设法找到了类型*MyModel,而MyModel不是因为我似乎无法找到指针 func getType( m interface{} ) reflect.Type { t := reflect.TypeOf( m ); v := reflect.ValueOf( m ); if t.Kind() == reflect.Ptr { if v.IsValid()
接口{}
,而输入值可能是var m[]*MyModel
我已经设法找到了类型*MyModel
,而MyModel
不是因为我似乎无法找到指针
func getType( m interface{} ) reflect.Type {
t := reflect.TypeOf( m );
v := reflect.ValueOf( m );
if t.Kind() == reflect.Ptr {
if v.IsValid() && !v.IsNil() {
return getType( v.Elem().Interface() );
}
panic( "We have a problem" );
}
if t.Kind() == reflect.Slice {
if v.Len() == 0 {
s := reflect.MakeSlice( t , 1 , 1 );
return getType( s.Interface() );
}
return getType( v.Index( 0 ).Interface() );
}
return t;
}
有可能吗?您可以使用获取类型的元素类型,该类型适用于数组
,Chan
,映射
,Ptr
和切片
您可以运行一个循环并“导航”到该类型的元素类型,直到该类型既不是指针也不是片(如果需要,也不是数组、chan、map)
因此,简单的解决方案是:
func getElemType(a interface{}) reflect.Type {
for t := reflect.TypeOf(a); ; {
switch t.Kind() {
case reflect.Ptr, reflect.Slice:
t = t.Elem()
default:
return t
}
}
}
测试它:
type MyModel struct{}
fmt.Println(getElemType(MyModel{}))
fmt.Println(getElemType(&MyModel{}))
fmt.Println(getElemType([]MyModel{}))
fmt.Println(getElemType([]*MyModel{}))
fmt.Println(getElemType(&[]*MyModel{}))
fmt.Println(getElemType(&[]****MyModel{}))
fmt.Println(getElemType(&[][]**[]*[]***MyModel{}))
var p *[][]**[]*[]***MyModel
fmt.Println(p) // It's nil!
fmt.Println(getElemType(p))
输出(在上尝试):
注意#2:由于实现包含一个循环而不限制迭代计数,递归类型的值将使其进入一个无止境的循环,例如:
type RecType []RecType
getElemType(RecType{}) // Endless loop!
不加评论地否决?这是一个很好的反馈。你的解决方案很有魅力。我真的不明白,为什么需要
for
循环,但它可以工作,而不仅仅是t:=reflect.TypeOf(a)
。你能解释一下吗?@MichaelSazonov如果你从类型[]**MyModel
开始,Elem()
将返回一个描述**MyModel
的类型。再次调用Elem()
将返回您的*MyModel
,再次调用Elem()
将得到MyModel
。调用Elem()
将剥离一个“类型层”。你需要一个循环来移除所有的“层”,直到你剩下的是“裸”类型。。。非常感谢你!
if a == nil {
return nil
}
type RecType []RecType
getElemType(RecType{}) // Endless loop!