interface{}
is a type, and reflect.TypeOf()
expects a value. So you can't pass the literal interface{}
to it. You can only pass a value.
Back to the original question. Let's see a struct
example:
type My struct {
A int
B interface{}
C io.Reader
}
You want to tell if the type of a field is interface{}
. Acquire the reflect.Type
of the struct
type, then you can access the fields using Type.Field()
or Type.FieldByName()
.
This gives you a value of type reflect.StructField
which stores the type of the field.
So far so good. But what should we compare it to? interface{}
is an interface type with 0 methods. You can't have (instantiate) a value of that type. You can only have values of concrete types, but yes, they may be wrapped in an interface type.
You could use Type.Kind
, and compare it to reflect.Interface
, which tells you if it's an interface, but this is true
for all interface types. You could also check if it has 0 methods with Type.NumMethod()
, which must be 0 for interface{}
, but other interfaces could also have 0 methods...
You may use Type.Name
, but since interface{}
is a unnamed type, its name is the empty string ""
(and there are other unnamed types). You may use Type.String()
which returns "interface {}"
for the empty 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 {}",
)
}
Output (try it on the 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
You might find this related question interesting / useful: Identify non builtin-types using reflect