Skip to content

Instantly share code, notes, and snippets.

@asilvr
Last active July 14, 2019 22:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asilvr/4d4da3cdc8180c5a9740d2890d833923 to your computer and use it in GitHub Desktop.
Save asilvr/4d4da3cdc8180c5a9740d2890d833923 to your computer and use it in GitHub Desktop.
This example shows how Go delegates covariance to the developer
package main
import (
"fmt"
)
// Animal represents any animal on Earth.
type Animal interface {
Noise() string
}
// Dog represents an animal that is often a pet.
type Dog struct{}
// Noise returns the noise a Dog makes.
func (Dog) Noise() string {
return "Woof!"
}
// Print noises prints each animal's noise.
func PrintNoises(as []Animal) {
for _, a := range as {
fmt.Println(a.Noise())
}
}
// Static type check that Dog is an Animal.
var _ Animal = Dog{}
// Bad static type check that []Dog is not equivalent to a []Animal.
// var _ []Animal = []Dog{}
func main() {
// Program 1: This compiles and runs successfully.
animals := []Animal{Dog{}}
PrintNoises(animals)
// Program 2: This does not compile and run successfully.
// dogs := []Dog{Dog{}}
// PrintNoises(dogs)
// Program 3: This fixes the compile and run issues in program 2.
// dogs := []Dog{Dog{}}
// New logic: convert the slice of dogs to a slice of animals
// animals := []Animal{}
// for _, d := range dogs {
// animals = append(animals, Animal(d))
// }
// PrintNoises(animals)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment