创建结构时正确使用接口

I'm trying to write a small program in which I have a few packages, each with a struct that implements an interface. The idea is that based on user input, I can choose what package to use to build a particular struct and then call a function on it that they're all supposed to have. Since I don't know the type ahead of time, I was under the impression that I could use a interface{} and use that as a forward declaration (see the last code snippet). I have something that looks like this:

package foo

type FooInput struct {
    Bar string
    Baz    int
}

type Foo interface {
    Ding()
    Dong()
}

In another package, bob, I have something like:

type Bob struct {
    foo.FooInput
}
func (mybob *Bob) Ding() {}
func (mybob *Bob) Dong() {}
func MakeBob(foo_input foo.FooInput) (*Bob, error) {
    my_bob := Bob{foo_input}
    return &my_bob, nil
}

In my main package, I have something that looks like so:

data = foo.FooInput("awyiss", 1}
var something interface{}
var err error

switch some_string {
case "foo":
    something, err = bob.MakeBob(foo_input)
case "bar":
    // imagine bar is like foo
    something, err = bar.MakeBar(foo_input)
// imagine other cases
}
something.Dong()

When running / building / etc, I get the following error:

something.Dong undefined (type interface {} is interface with no methods)

I'm a bit confused as to what I'm doing wrong... any clarifiers on how I should use interface{} (if at all) would be extremely helpful!

The variable something is declared as the empty interface. There are no methods on the empty interface. To call the Dong method, declare something as a foo.Foo .

Change

var something interface{}

to

var something foo.Foo 

This assumes that bar being like foo means that bar satisfies the foo.Foo interface.

If looks, that you are a bit confused. Please, choose - one of two possibilities. If all the types, that you want to put into variable "something" has methods Ding, and Dong - than define interface for it. Foo is not the best name, better is DingDonger (https://golang.org/doc/effective_go.html#interface-names).

After:

var something DingDonger

each assign to something will be checked, whether type really has required methods, and therefore something.Ding() can not cause an error.

If any variable is type interface{} no one knows, whether it has or not such method and you have to use type assertion (https://golang.org/doc/effective_go.html#interface_conversions) to verify whether method is implemented.