package main import ( "bufio" "fmt" "os" "strings" ) type Animal interface { Eat() Move() Speak() } type Cow struct { } func (cow Cow) Eat() { fmt.Println("grass") } func (cow Cow) Move() { fmt.Println("walk") } func (cow Cow) Speak() { fmt.Println("moo") } type Bird struct { } func (bird Bird) Eat() { fmt.Println("worms") } func (bird Bird) Move() { fmt.Println("fly") } func (bird Bird) Speak() { fmt.Println("peep") } type Snake struct { } func (snake Snake) Eat() { fmt.Println("mice") } func (snake Snake) Move() { fmt.Println("slither") } func (snake Snake) Speak() { fmt.Println("hsss") } func createNewAnimal(animalName string, animalType string, animalMap map[string]Animal) { switch animalType { case "cow": animalMap[animalName] = Cow{} case "bird": animalMap[animalName] = Bird{} case "snake": animalMap[animalName] = Snake{} default: fmt.Println("Invalid animal type") return } fmt.Println("Created it!") } func queryAnimal(animalName string, animalAction string, animalMap map[string]Animal) { animal, ok := animalMap[animalName] if !ok { fmt.Printf("Could not find animal %s\n", animalName) return } switch animalAction { case "eat": animal.Eat() case "move": animal.Move() case "speak": animal.Speak() } } func main() { scanner := bufio.NewScanner(os.Stdin) animalMap := make(map[string]Animal) for { fmt.Print(">") var fields []string if scanner.Scan() { fields = strings.Fields(scanner.Text()) if len(fields) != 3 { fmt.Println("Wrong number of arguments") continue } } switch fields[0] { case "newanimal": createNewAnimal(fields[1], fields[2], animalMap) case "query": queryAnimal(fields[1], fields[2], animalMap) default: fmt.Println("Invalid command") } } }