Get the reflect.Kind of a type which is based on a primitive type

Viewed 726

I would like to get the reflect.Kind as a reflect.Interface for a type which implements an interface but where its implementation is based on a primitive type: type id string

An alternative answer for this could be how to get any kind of reflect.Type that returns reflect.Interfaces when calling Kind().

Here is a full example on the Go Playground:

type ID interface {
    myid()
}

type id string

func (id) myid() {}

func main() {
    id := ID(id("test"))
    
    fmt.Println(id)
    fmt.Println(reflect.TypeOf(id))
    
    // How to get the kind to return "reflect.Interface" from the var "id"?
    fmt.Println(reflect.TypeOf(id).Kind())
}
1 Answers

reflect.TypeOf() (and reflect.ValueOf()) expects an interface{}. Basically whatever value you pass to reflect.TypeOf(), if it's not already an interface value, it will be wrapped in an interface{} implicitly. If the passed value is already an interface value, then the concrete value stored in it will be passed as a interface{}.

In order to avoid this "repacking", this is one of those rare cases when a pointer to interface makes sense, in fact you can't avoid it here. You have to pass a pointer to the interface value.

So if you pass a pointer to interface, this pointer will be wrapped in an interface{} value. You may use Type.Elem() to get the type descriptor of the "pointed type": that is, the element type of the pointer type, which will be the type descriptor of the interface type you're looking for.

Example:

id := ID(id("test"))

fmt.Println(id)
t := reflect.TypeOf(&id).Elem()
fmt.Println(t)

fmt.Println(t.Kind())

Which outputs (try it on the Go Playground):

test
main.ID
interface

See related question: What is the difference between reflect.ValueOf() and Value.Elem() in go?

Related