Reputation: 397
If I have an interface being passed into a function, is there a way to tell if the item passed in is a struct or a pointer to a struct? I wrote this silly test to illustrate what I need to figure out.
type MyStruct struct {
Value string
}
func TestInterfaceIsOrIsntPointer(t *testing.T) {
var myStruct interface{} = MyStruct{Value: "hello1"}
var myPointerToStruct interface{} = &MyStruct{Value: "hello1"}
// the IsPointer method doesn't exist on interface, but I need something like this
if myStruct.IsPointer() || !myPointerToStruct.IsPointer() {
t.Fatal("expected myStruct to not be pointer and myPointerToStruct to be a pointer")
}
}
Upvotes: 13
Views: 7706
Reputation: 3978
func isStruct(i interface{}) bool {
return reflect.ValueOf(i).Type().Kind() == reflect.Struct
}
You can test via changing type according to your needs such as reflect.Ptr
. You can even get pointed value with reflect.Indirect(reflect.ValueOf(i))
after you ensured it's a pointer.
Addition:
It seems reflect.Value
has a Kind
method so reflect.ValueOf(i).Kind()
is enough.
Upvotes: 12
Reputation: 4833
You could use the reflect package:
i := 42
j := &i
kindOfJ := reflect.ValueOf(j).Kind()
fmt.Print(kindOfJ == reflect.Ptr)
Upvotes: 3
Reputation: 4411
If you know the "real" type of the interface, you can simply use a type switch
:
type MyStruct struct {
Value string
}
func TestInterfaceIsOrIsntPointer(t *testing.T) {
var myStruct interface{} = MyStruct{Value: "hello1"}
var myPointerToStruct interface{} = &MyStruct{Value: "hello1"}
// the IsPointer method doesn't exist on interface, but I need something like this
switch myStruct.(type) {
case MyStruct:
// ok
break
case *MyStruct:
// error here
break
}
switch myPointerToStruct.(type) {
case MyStruct:
// error here
break
case *MyStruct:
// ok
break
}
}
The code is longer but at least you don't need to use the reflect
package.
Upvotes: 3