这个问题是关于在golang中“继承”接口实现的最干净方法。我了解Go没有继承权;这个问题是关于人们如何以其他方式实现的,因此是关于继承的引号。
假设有一个定义的标准库接口,例如container/heap
:https://golang.org/pkg/container/heap/#Interface
可以说有一个名为.go
的{{1}}文件可以实现该接口:
pq.go
现在假设我只想在//pq.go
import ("container/heap")
type PriorityQueue []*Vertex
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
...
}
func (pq PriorityQueue) Swap(i, j int) {
...
}
func (pq *PriorityQueue) Push(x interface{}) {
...
}
func (pq *PriorityQueue) Pop() interface{} {
...
}
中对此命名为MaxPQ
的Tiny变体,在这里我想覆盖maxpq.go
的单个实现细节,例如,覆盖{ {1}}。在不从字面上复制最后一个文件,更改类型名称和更改单个功能(例如pq.go
的实现)的情况下如何实现?
意思是,有没有办法对与另一个非常相似的接口进行新的实现?
这样做,实际上是将其复制过来,似乎很麻烦,并且需要在多个地方进行更改:
Less(..)
答案 0 :(得分:1)
有多种方法可以执行此操作。
您可以基于原始类型定义一个新类型,并委派所有方法:
type OriginalType struct {...}
func (o OriginalType) F() {...}
type NewType OriginalType
func (n NewType) F() { OriginalType(n).F() }
因此,您需要重新定义原始类型的所有方法,因为NewType不会“继承”原始类型的方法。
您可以嵌入:
type NewType struct {
OldType
}
现在您有了NewType.F()函数,但是它将在NewType的OldType部分上运行。如果要重新声明,可以:
func (n NewType) F() {
n.OldType.F();
// Do more stuff
}
如果您通过接口传递任何一个实例,它将像继承一样工作。那就是:
type IntF interface {
F()
}
func f(v IntF) {
v.F()
}
如果传递NewType,则将调用NewType.F。
但是,您必须传递一个接口,而不能传递嵌入式结构来获得封闭对象的行为:
func f(v OriginalType) {
v.F()
}
func main() {
n:=NewType()
// f(n) Won't work
f(n.OriginalType)
上面,仅将n的OriginalType部分发送到函数f,然后将调用OriginalType.F。
答案 1 :(得分:0)
您可以使用合成方法尝试类似的操作。
type iTemp interface {
func1()
func2()
}
type base struct {
}
func (base) func1() {
fmt.Println("base func1")
}
func (base) func2() {
fmt.Println("base func2")
}
type child struct {
base
}
func (child) func1() {
fmt.Println("child func1")
}
func main(){
printMessage(base{})
printMessage(child{})
}
func printMessage(t iTemp) {
t.func1()
t.func2()
}
输出:
base func1
base func2
child func1
base func2
在子结构中,您正在提供基类的func1函数的新实现,但是您仍然可以访问基类的实现,仍然可以使用child{}.base.func1()