In the Go language, when you define an interface, you only need to implement the functions and your type automatically "implements" that interface, without explicitly saying so.

For example:

type Food interface {
  Eat()
}

type Apple struct {
}

func (a *Apple) Eat() {
}

func main() {
  var food Food
  food = &Apple{}
  food.Eat()
}

Recently I've worked a lot more with interfaces, and something that's not very clear from the example above is that interfaces work like pointers. Here's some code to illustrate:

type Food interface {
    Eat()
}

type Apple struct {
    color string
}

func (a *Apple) Eat() {
    fmt.Printf("Eating a %s apple.\n", a.color)
}

type Pizza struct {
    size  string
    style string
}

func (p *Pizza) Eat() {
    fmt.Printf("Eating a %s %s pizza.\n", p.size, p.style)
}

func main() {
    // Normal variable containing an object of type Apple
    var apple1 Apple
    apple1 = Apple{"green"}
    apple1.Eat() // prints "Eating a green apple."

    // Variable containing a pointer to an object of type Apple
    var apple2 *Apple
    apple2 = &Apple{"red"} // We have to assign the "address" of the object
    apple2.Eat()           // prints "Eating a red apple."

    // This variable also works like a pointer (see assignments below)
    var snack Food
    // snack = Apple{"red"} -- Doesn't work
    snack = &Apple{"red"}
    snack.Eat() // prints "Eating a red apple."
    snack = &Pizza{"large", "napolitan"}
    snack.Eat() // prints "Eating a large pepperoni pizza."

    // Mandatory slice example
    items := []Food{&apple1, apple2, snack}
    for _, item := range items {
        item.Eat()
    }
}
Previous on Go
Mastodon Mastodon