【发布时间】:2017-08-05 07:59:32
【问题描述】:
【问题讨论】:
标签: pointers go struct interface
【问题讨论】:
标签: pointers go struct interface
让我解释一下:
首先在这个函数中:
func (predator Cat) eatingVictim(victim *Mouse) {
fmt.Println(predator.name + "'s eating victim " + victim.name)
predator.hungry = false
victim.alive = false
}
你想通过草食动物。这是一个糟糕的解决方案,因为您不会 在此处使用 Herbivore 接口中的方法。更好的方法是定义 另一个界面。
type Animal interface {
GetName() string
SetAlive(bool)
}
并为鼠标(如果你愿意,也可以为猫)实现它:
func (m *Mouse) GetName() string {
return m.name
}
func (m *Mouse) SetAlive(alive bool) {
m.alive = alive
}
然后将 Predator 界面改为:
type Predator interface {
eatingVictim(victim Animal)
}
并为 Cat 实现它
func (predator *Cat) eatingVictim(victim Animal) {
fmt.Println(predator.name + "'s eating victim " + victim.GetName())
predator.hungry = false
victim.SetAlive(false)
}
我需要提一下,如果你希望你的原始结构 被修改然后你需要传递一个指向结构的指针,而不是一个结构 接收者参数:
此处鼠标结构不会被修改。只有一个副本。
func (herbivore Mouse) eatingGrass() {
fmt.Println(herbivore.name + "'s eating a grass.. ^___^")
herbivore.hungry = false
}
这是固定版本:
func (herbivore *Mouse) eatingGrass() {
fmt.Println(herbivore.name + "'s eating a grass.. ^___^")
herbivore.hungry = false
}
如果您想对此进行更好的解释 - 请访问 my blog post
最后一件事 - 作为最佳实践 - 如果您在您的方法之一中使用了 Struct 指针 type 那么它们都应该有一个指向它的指针。
最终解决方案:
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)
}
【讨论】:
首先你需要在接口中添加一个Name()和一个SetAlive()方法并导出eatingGrass:
type Herbivore interface {
Name()string
SetAlive(bool)
EatingGrass()
}
那么你需要为鼠标实现Name():
func (herbivore *Mouse) Name()string {
return Mouse.name
}
然后对 SetAlive 执行相同操作。
现在可以使用界面了:
func (predator Cat) eatingVictim(h Herbivore) {
fmt.Println(predator.name + "'s eating victim " + h.Name())
predator.hungry = false
h.SetAlive(false)
}
注意:您应该实现*Mouse 的所有功能。因为当您设置结构的某些值时,您应该为指针而不是结构实现方法。否则你可能会有错误。
在实现时,最好像这样定义变量:
func (m *Mouse) Name() string {
return m.name
}
【讨论】: