44

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?

4 Answers 4

78

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
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

What about if you dont know the type of interface? baz in your example
@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.
Is there a way to do this with slices?
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 ....
@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.
7

use reflect

reflect.ValueOf(myStruct).Interface().(newType)

1 Comment

reflect can do this, but it's a heavy and dangerous way of conversion. There is a much easier way, described in accepted answer.
2

Converting a struct to interface can be achieved like this. Where i is an assign data structure.

var j interface{} = &i

1 Comment

This is should be the right answer, so from the question it can be something like this: var newFoo interface{} = &foo{} bar(newFoo)
0

Not fully-related, but I googled the question "convert interface struct to pointer" and get here.

So, just make a note: to convert an interface of T to interface of *T:

//
// Return a pointer to the supplied struct via interface{}
//
func to_struct_ptr(obj interface{}) interface{} {
    vp := reflect.New(reflect.TypeOf(obj))
    vp.Elem().Set(reflect.ValueOf(obj))
    return vp.Interface()
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.