我正在使用reflect包来确定struct字段的类型 interface{}
我想做这样的比较(在哪里t
是reflect.Type
):
if t == reflect.TypeOf(interface{}) { }
问题是编译器抱怨:type interface {} is not an expression
.
反正有没有检查结构域的类型是否是interface{}
?
您可以Y
通过创建nil实例并使用反射来获取接口的类型:
yType := reflect.TypeOf((*Y)(nil)).Elem()
然后使用表达式
reflect.TypeOf(x).Implements(yType)
检查类型是否实现了接口.
接口本身无法实例化.作为空接口的接口{}接口由所有类型实现,因此所有字段都实现该接口.
https://play.golang.org/p/gRfheIW_9Y
实际上它也适用于空接口{}本身,但这将始终返回true(如果我没有遗漏某些东西):
https://play.golang.org/p/29rWP4LtIo
interface{}
是一种类型,并reflect.TypeOf()
期望一个值.所以你无法将文字传递interface{}
给它.您只能传递一个值.
回到原来的问题.我们来看一个struct
例子:
type My struct { A int B interface{} C io.Reader }
您想知道字段的类型是否为interface{}
.获取reflect.Type
的的struct
类型,那么你可以使用访问域Type.Field()
或Type.FieldByName()
.
这将为您提供reflect.StructField
存储字段类型的类型值.
到现在为止还挺好.但是我们应该将它与什么进行比较?interface{}
是一个有0方法的接口类型.您不能拥有(实例化)该类型的值.您只能拥有具体类型的值,但是,它们可能包含在接口类型中.
您可以使用Type.Kind
并比较它reflect.Interface
,它会告诉您它是否是一个接口,但这true
适用于所有接口类型.您还可以检查它是否有0方法Type.NumMethod()
,必须为0 interface{}
,但其他接口也可以有0方法...
您可以使用Type.Name
,但由于interface{}
是未命名的类型,因此其名称为空字符串""
(还有其他未命名的类型).您可以使用Type.String()
哪个返回"interface {}"
空接口:
t := reflect.TypeOf(My{}) for i := 0; i < t.NumField(); i++ { f := t.Field(i) fmt.Printf("Field %q, type: %-12v, type name: %-8q, is interface{}: %v\n", f.Name, f.Type, f.Type.Name(), f.Type.String() == "interface {}", ) }
输出(在Go Playground上试试):
Field "A", type: int , type name: "int" , is interface{}: false Field "B", type: interface {}, type name: "" , is interface{}: true Field "C", type: io.Reader , type name: "Reader", is interface{}: false
您可能会发现此相关问题有趣/有用:使用反射识别非内置类型