首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >go虚拟函数仿真

go虚拟函数仿真
EN

Stack Overflow用户
提问于 2016-04-27 08:42:10
回答 2查看 908关注 0票数 1

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

代码语言:javascript
复制
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继承模型:在这种情况下,这个*B和这个*A是不同的指针,但我想知道是否可以对这种行为进行一些模拟,在最后一次调用中,DoVirtual将从B类中使用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-27 09:16:24

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

我认为对实施和动机的最好解释是来自Rob的越少越好。

票数 3
EN

Stack Overflow用户

发布于 2016-04-27 09:17:41

我的简单模拟,您可以通过一些reflect,代码生成,甚至RPC来改进它。其主要思想是添加一个虚拟方法表,并像c++那样自行分派。

代码语言:javascript
复制
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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36884609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档