去虚拟功能模拟

时间:2016-04-27 08:42:11

标签: go virtual

是否存在一些在go中实现虚函数行为的技巧?我有以下例子。

package main

import "fmt"

type A struct {
}

type B struct {
*A
}

func (this *A) Do() {
    fmt.Println("IM DO")
    this.DoVirtual()
}

func (this *A) DoVirtual() {
    fmt.Println("IM DoVirtual Default implementation")
}

func (this *B) DoVirtual() {
    fmt.Println("IM DoVirtual B implementation")
}

func main() {
    a := &A{}
    a.Do()
    fmt.Println("----")
    b := &B{}
    b.DoVirtual()
    b.Do() // How to make here B.DoVirtual call
}

最后一次Do()调用也使用默认的DoVirtual实现,实际上并不是我想要的。之所以如此,那就是go lang iheritance model:这个* B和这个* A在这种情况下是不同的指针,但我想知道是否有可能对上次调用中的DoVirtual将从B类中使用的这种行为进行一些模拟。

2 个答案:

答案 0 :(得分:3)

当编译器选择func (this *A) Do() {时,封闭的B消失了,不再可访问。 Go不支持is-a构造,只支持has-a(组合)。如果实现func (this *B) Do() {,它将取代* A上的Do()。当然,这并不是你想要的。

我认为实施和动机的最佳解释是来自Rob Pike的Less is exponentially more

答案 1 :(得分:2)

我的简单模拟,你可以通过一些reflect,代码生成甚至RPC来改进它。主要的想法是添加一个虚方法表,并自己调度,就像c ++一样。

package main

import "fmt"

type A struct {
virFunDispatcher func(funAndParams ... interface{})
}

func newA() *A{
    return &A{func(funAndParams ... interface{}){
        fun := funAndParams[0].(string)
        switch(fun){
            case "DoVirtual":
                fmt.Println("IM DoVirtual Default implementation")
        }
    }}
}

type B struct {
*A
}


func newB() *B{
    a := A{func(funAndParams ... interface{}){
        fun := funAndParams[0].(string)
        switch(fun){
            case "DoVirtual":
                fmt.Println("IM DoVirtual B implementation")
        }
    }}
    return &B{&a}
}

func (this *A) Do() {
    fmt.Println("IM DO")
    this.virFunDispatcher("DoVirtual")
}

func (this *A) DoVirtual() {
    fmt.Println("IM DoVirtual Default implementation")
}

func (this *B) DoVirtual() {
    fmt.Println("IM DoVirtual B implementation")
}

func main() {
    a := newA()
    a.Do()
    fmt.Println("----")
    b := newB()
    b.DoVirtual()
    b.Do() // How to make here B.DoVirtual call
}

https://play.golang.org/p/Iw30lVOhuC

相关问题