convert struct pointer to interface{}

79,846

Solution 1

To turn *foo into an interface{} is trivial:

f := &foo{}
bar(f) // every type implements interface{}. Nothing special required

In order to get back to a *foo, you can either do a type assertion:

func bar(baz interface{}) {
    f, ok := baz.(*foo)
    if !ok {
        // baz was not of type *foo. The assertion failed
    }

    // f is of type *foo
}

Or a type switch (similar, but useful if baz can be multiple types):

func bar(baz interface{}) {
    switch f := baz.(type) {
    case *foo: // f is of type *foo
    default: // f is some other type
    }
}

Solution 2

use reflect

reflect.ValueOf(myStruct).Interface().(newType)
Share:
79,846
lf215
Author by

lf215

Updated on January 16, 2022

Comments

  • lf215
    lf215 over 2 years

    If I have:

       type foo struct{
       }
    
       func bar(baz interface{}) {
       }
    

    The above are set in stone - I can't change foo or bar. Additionally, baz must converted back to a foo struct pointer inside bar. How do I cast &foo{} to interface{} so I can use it as a parameter when calling bar?

  • Juan de Parras
    Juan de Parras about 9 years
    What about if you dont know the type of interface? baz in your example
  • ANisus
    ANisus about 9 years
    @JuandeParras: If you don't know what kind of types baz might be, then you will have to work with reflection (import "reflect"). This is how packages like encoding/json can encode basically any type without knowing before hand.
  • jocull
    jocull almost 9 years
    Is there a way to do this with slices?
  • Saim Mahmood
    Saim Mahmood over 4 years
    i dont get this. you are sending an object with address of struct foo but in the function it accepts an interface? when I try this and print the type using fmt.Printf it says the type is a struct pointer, not interface ....
  • ANisus
    ANisus over 4 years
    @SaimMahmood fmt.Printf will always receive its arguments as interfaces. What it does is telling you the type inside the interface. That means that fmt.Printf("%T", f) and fmt.Printf("%T", interface{}(f)) is the same. The only difference is that in the latter, I did a redundant explicit conversion.
  • alexykot
    alexykot about 4 years
    reflect can do this, but it's a heavy and dangerous way of conversion. There is a much easier way, described in accepted answer.