Go 如何使用reflect检查结构字段的类型是否为interface{}?

Go 如何使用reflect检查结构字段的类型是否为interface{}?,go,reflection,Go,Reflection,我正在使用reflect包来确定结构字段的类型是interface{} 我想这样做比较(其中t是reflect.Type): 问题是编译器抱怨:类型接口{}不是表达式 是否仍要检查结构字段的类型是否为接口{}?您可以通过创建nil实例并使用反射来获取接口的类型Y: yType := reflect.TypeOf((*Y)(nil)).Elem() 然后使用表达式 reflect.TypeOf(x).Implements(yType) 检查类型是否实现了接口 接口本身无法实例化。接口{}接口是

我正在使用reflect包来确定结构字段的类型是
interface{}

我想这样做比较(其中
t
reflect.Type
):

问题是编译器抱怨:
类型接口{}不是表达式


是否仍要检查结构字段的类型是否为
接口{}

您可以通过创建nil实例并使用反射来获取接口的类型
Y

yType := reflect.TypeOf((*Y)(nil)).Elem()
然后使用表达式

reflect.TypeOf(x).Implements(yType)
检查类型是否实现了接口

接口本身无法实例化。接口{}接口是由所有类型实现的空接口,因此所有字段都实现了该接口

实际上,它也适用于空接口{}本身,但这将始终返回true(如果我没有遗漏某些内容):


接口{}
是一种类型,需要一个值。因此,您不能将文本
接口{}
传递给它。您只能传递一个值

回到原来的问题。让我们看一个
struct
示例:

type My struct {
    A int
    B interface{}
    C io.Reader
}
您想知道字段的类型是否为
interface{}
。获取
struct
类型的名称,然后可以使用
type.Field()
type.FieldByName()
访问字段

这将为您提供一个类型值,该值存储字段的类型

到目前为止还不错。但我们应该把它与什么作比较呢<代码>接口{}是一种具有0个方法的接口类型。您不能拥有(实例化)该类型的值。您只能有具体类型的值,但是可以,它们可以包装在接口类型中

您可以使用
Type.Kind
,并将其与
reflect.Interface
进行比较,这会告诉您它是否是一个接口,但对于所有接口类型,这都是
true
。您还可以检查它是否有0个
Type.NumMethod()
,对于
接口{}
,它必须是0,但其他接口也可能有0个方法

您可以使用
Type.Name
,但由于
接口{}
是未命名类型,因此其名称为空字符串
“”
(还有其他未命名类型)。您可以使用
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 {}",
    )
}

您可能会发现这个相关的问题很有趣/有用:

如果Y是一个
接口{}
,我得到一个错误:
不能调用非函数Y(类型接口{})
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 {}",
    )
}
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