Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
golang:关于接口实现继承的问题-堆栈溢出_Go - Fatal编程技术网

golang:关于接口实现继承的问题-堆栈溢出

golang:关于接口实现继承的问题-堆栈溢出,go,Go,这个问题是关于在golang中继承接口实现的最干净的方法。我明白围棋没有继承权;这个问题是关于人们如何以其他方式实现它,因此关于继承的引用 假设定义了一个标准库接口,例如容器/堆: 假设有一个名为pq.go的.go文件实现了该接口: //pq.go import ("container/heap") type PriorityQueue []*Vertex func (pq PriorityQueue) Len() int { return len(pq) } func (pq Priori

这个问题是关于在golang中继承接口实现的最干净的方法。我明白围棋没有继承权;这个问题是关于人们如何以其他方式实现它,因此关于继承的引用

假设定义了一个标准库接口,例如容器/堆:

假设有一个名为pq.go的.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.go中有一个很小的变体,称为MaxPQ,用于覆盖pq.go的单个实现细节,例如,覆盖较少。。。如何在不复制上一个文件、更改类型名称和更改单个函数的实现(例如,less)的情况下实现这一点

也就是说,有没有一种方法可以使一个接口的新实现与另一个接口非常相似

这样做,从字面上复制它,似乎是激烈的,需要在多个地方进行更改:

//maxpq.go
import ("container/heap")
type MaxPriorityQueue []*Vertex

func (pq MaxPriorityQueue) Len() int { return len(pq) }

func (pq MaxPriorityQueue) Less(i, j int) bool {
...
}

func (pq MaxPriorityQueue) Swap(i, j int) {
...
}

func (pq *MaxPriorityQueue) Push(x interface{}) {
...
}

func (pq *MaxPriorityQueue) Pop() interface{} {
...
}

有多种方法可以做到这一点

可以基于原始类型定义新类型,并委托所有方法:

type OriginalType struct {...}

func (o OriginalType) F() {...}

type NewType OriginalType

func (n NewType) F() { OriginalType(n).F() }
这样,您需要重新定义原始类型的所有方法,因为新类型不会继承OriginalType的方法

您可以嵌入:

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将被调用。

您可以使用composition尝试类似的操作

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  

在child struct中,您提供了基类的func1函数的新实现,但是您仍然可以访问基类实现,您仍然可以使用child{}.base.func1调用它。

Go中没有继承。@Adrian我知道Go没有继承;这个问题是关于人们如何以其他方式实现它。那么你能澄清一下你的问题吗?“你反复引用继承,但你说你知道根本没有继承。”阿德里安编辑。“汤米,你考虑过嵌入吗?”?