Skip to content

Instantly share code, notes, and snippets.

@mprymek
Last active February 24, 2018 10:02
Show Gist options
  • Save mprymek/052b443223147b04fb0efcf08e5df02d to your computer and use it in GitHub Desktop.
Save mprymek/052b443223147b04fb0efcf08e5df02d to your computer and use it in GitHub Desktop.
/*
Duck typing in golang example.
You can try it here: https://play.golang.org/p/kHRnpmA206r
*/
package main
import (
"fmt"
"reflect"
)
type Animal struct {
Name string
}
func (a Animal) String() string {
return fmt.Sprintf("<Animal %s>", a.Name)
}
func (a Animal) GetName() string {
return a.Name
}
type Lion struct {
Name string
}
func (l Lion) Roar() {
fmt.Printf("RRRRRRoarghrrrrr! I'm %s!\n", l.Name)
}
func (l Lion) String() string {
return fmt.Sprintf("<Lion %s>", l.Name)
}
type Named interface {
GetName() string
}
type Roaring interface {
Roar()
}
func genericRoar(x interface{}) {
st := reflect.TypeOf(x)
fmt.Printf("Type is %v\n\n", st)
fmt.Println("Roaring using switch...")
switch v := x.(type) {
case Roaring:
v.Roar()
case Named:
fmt.Printf("%s can't roar\n", v.GetName())
default:
fmt.Println("Can't roar")
}
fmt.Println("\nRoaring using reflection...")
roar, ok := st.MethodByName("Roar")
if !ok {
switch v := x.(type) {
case Named:
fmt.Printf("%s can't roar\n", v.GetName())
default:
fmt.Println("Can't roar")
}
} else {
fmt.Printf("Roar method is %v\n", roar)
x.(interface{Roar()}).Roar()
reflect.ValueOf(x).MethodByName("Roar").Call([]reflect.Value{})
}
}
func main() {
a := &Animal{"Chuchundra"}
fmt.Printf("Creature is %v\n", a)
genericRoar(a)
fmt.Println()
l := &Lion{"Simba"}
fmt.Printf("Creature is %v\n", l)
genericRoar(l)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment