How can I use interface Herbivore instead *Mouse in line 30?
I want to pass to method eatingVictim
different structs which implements Herbivore interface, not only Mouse
How can I use interface Herbivore instead *Mouse in line 30?
I want to pass to method eatingVictim
different structs which implements Herbivore interface, not only Mouse
Let me explain:
First of all in this function:
func (predator Cat) eatingVictim(victim *Mouse) {
fmt.Println(predator.name + "'s eating victim " + victim.name)
predator.hungry = false
victim.alive = false
}
You want to pass Herbivore. This is a bad solution because you will not use methods from Herbivore interface here. Better approach is to define another interface.
type Animal interface {
GetName() string
SetAlive(bool)
}
And implement it for Mouse (and Cat if you wish):
func (m *Mouse) GetName() string {
return m.name
}
func (m *Mouse) SetAlive(alive bool) {
m.alive = alive
}
Then change interface Predator to:
type Predator interface {
eatingVictim(victim Animal)
}
and implement it for Cat
func (predator *Cat) eatingVictim(victim Animal) {
fmt.Println(predator.name + "'s eating victim " + victim.GetName())
predator.hungry = false
victim.SetAlive(false)
}
I need to mention that if you want your original structs to be modified then you need to pass a pointer to struct, not a struct as receiver argument:
Here Mouse struct will not be modified. Only a copy of it.
func (herbivore Mouse) eatingGrass() {
fmt.Println(herbivore.name + "'s eating a grass.. ^___^")
herbivore.hungry = false
}
And here is the fixed version:
func (herbivore *Mouse) eatingGrass() {
fmt.Println(herbivore.name + "'s eating a grass.. ^___^")
herbivore.hungry = false
}
If you want better explanation for this - then visit my blog post
The last thing - as best practice - if you used Struct pointer in one of the methods of your type then all of them should take a pointer to it.
Final solution:
package main
import "fmt"
type Predator interface {
eatingVictim(victim Animal)
}
type Herbivore interface {
eatingGrass()
}
type Animal interface {
GetName() string
SetAlive(bool)
}
type Cat struct {
name string
hungry bool
alive bool
}
type Mouse struct {
name string
hungry bool
alive bool
}
func (herbivore *Mouse) eatingGrass() {
fmt.Println(herbivore.name + "'s eating a grass.. ^___^")
herbivore.hungry = false
}
func (m *Mouse) GetName() string {
return m.name
}
func (m *Mouse) SetAlive(alive bool) {
m.alive = alive
}
func (predator *Cat) eatingVictim(victim Animal) {
fmt.Println(predator.name + "'s eating victim " + victim.GetName())
predator.hungry = false
victim.SetAlive(false)
}
func main() {
cat := Cat{"cat", true, true}
mouse := Mouse{"mouse", true, true}
fmt.Println(cat)
fmt.Println(mouse)
mouse.eatingGrass()
cat.eatingVictim(&mouse)
fmt.Println(cat)
fmt.Println(mouse)
}