我正在使用reflect包来确定结构字段的类型是interface{}
我想像这样进行比较(其中t
是reflect.Type
):
if t == reflect.TypeOf(interface{}) {
}
问题是编译器抱怨:type interface {} is not an expression
。
无论如何检查结构字段的类型是否为interface{}
?
答案 0 :(得分:6)
您可以通过创建nil实例并使用反射来获取接口Y
的类型:
yType := reflect.TypeOf((*Y)(nil)).Elem()
然后使用表达式
reflect.TypeOf(x).Implements(yType)
检查类型是否实现了接口。
接口本身无法实例化。作为空接口的interface {}接口由所有类型实现,因此所有字段都实现了该接口。
https://play.golang.org/p/gRfheIW_9Y
实际上它也适用于空接口{}本身,但这将始终返回true(如果我没有遗漏某些东西):
答案 1 :(得分:5)
interface{}
是一种类型,reflect.TypeOf()
需要一个值。因此,您无法将文字interface{}
传递给它。您只能传递一个值。
回到原来的问题。让我们看一个struct
示例:
type My struct {
A int
B interface{}
C io.Reader
}
您想知道字段的类型是否为interface{}
。获取struct
类型的reflect.Type
,然后您可以使用Type.Field()
或Type.FieldByName()
访问这些字段。
这为您提供了reflect.StructField
类型的值,用于存储字段的类型。
到目前为止一切顺利。但是我们应该将它与什么进行比较? interface{}
是一个包含0个方法的接口类型。您无法(实例化)该类型的值。您只能拥有具体类型的值,但是,它们可能包含在接口类型中。
您可以使用Type.Kind
,并将其与reflect.Interface
进行比较,后者会告诉您它是否为界面,但对于所有界面类型,这都是true
。您还可以检查它是否有0个Type.NumMethod()
方法,interface{}
必须为0,但其他接口也可以有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
您可能会发现此相关问题有趣/有用:Identify non builtin-types using reflect