我有两种类型,B和C,它们共享所有方法,但以不同方式实现其中一种。我想通过使用父类型A来表达这一点,包含共享方法的实现,并在A和B中嵌入A.(不要重复自己!)障碍是B和B之间的方法不同在许多共享方法中调用C.构建此类代码的惯用方法是什么?
我当前的实现看起来基本上是这样的(https://play.golang.org/p/RAvH_hBFDN;基于Dave Cheney的示例):
package main
import (
"fmt"
)
type Legger interface {
Legs() int
}
type Cat struct {
Name string
L Legger
}
// Cat has many methods like this, involving calling c.L.Legs()
func (c Cat) PrintLegs() {
fmt.Printf("I have %d legs.\n", c.L.Legs())
}
// OctoCat is a Cat with a particular implementation of Legs
type OctoCat struct {
Cat
}
func (c OctoCat) Legs() int {
return 8
}
// TetraCat has a different implementation of Legs
type TetraCat struct {
Cat
}
func (c TetraCat) Legs() int {
return 4
}
func main() {
c := TetraCat{Cat{"Steve",nil}}
c.L = &c
c.PrintLegs() // want 4
o := OctoCat{Cat{"Bob",nil}}
o.L = &o
o.PrintLegs() // want 8
}
类型定义本身看起来很干净,但是main
中的初始化代码很古怪(首先是struct literal中的nil
,然后是c.L = &c
,是什么?)。有更好的解决方案吗?
在is it possible to call overridden method from parent struct in golang?中提出了类似的模式,但是这是否是惯用的方法尚未得到解答。
答案 0 :(得分:1)
我会考虑解决这个问题的两种方法:
1。将您的代码重构为包含字段Cat
和Name string
的单个Legs int
类型:
package main
import (
"fmt"
)
type Cat struct {
Name string
Legs int
}
func (c *Cat) PrintLegs() {
fmt.Printf("I have %d legs.\n", c.Legs)
}
func main() {
c := &Cat{"Steve", 4}
c.PrintLegs() // want 4
o := &Cat{"Bob", 8}
o.PrintLegs() // want 8
}
https://play.golang.org/p/_PNAu3sgG8
2。取消Cat
类型,只需TetraCat
和OctoCat
实现Legger
界面:
package main
import (
"fmt"
)
type Legger interface {
Legs() int
}
func PrintLegs(l Legger) {
fmt.Printf("I have %d legs.\n", l.Legs())
}
// OctoCat is a Cat with a particular implementation of Legs
type OctoCat struct {
Name string
}
func (c *OctoCat) Legs() int {
return 8
}
// TetraCat has a different implementation of Legs
type TetraCat struct {
Name string
}
func (c *TetraCat) Legs() int {
return 4
}
func main() {
c := &TetraCat{"Steve"}
PrintLegs(c) // want 4
o := &OctoCat{"Bob"}
PrintLegs(o) // want 8
}