请教一个 go struct 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
croz
V2EX    Go 编程语言

请教一个 go struct 的问题

  •  
  •   croz 2017-05-02 16:07:13 +08:00 1841 次点击
    这是一个创建于 3097 天前的主题,其中的信息可能已经有所发展或是发生改变。
    type Parent struct{} func (p *Parent) A() { p.B() } func (p *Parent) B() { fmt.Println("parent.B()") } type Child struct { Parent } func (c *Child) B() { fmt.Println("child.B()") } 

    定义了两个结构体,Parent 和 Child
    Parent 有 A()和 B()两个方法,在 A 中调用了 B
    Child 只实现了 B(),然后按如下方式调用:

    func main() { p := &Parent{} c := &Child{} p.A() c.A() c.Parent.A() } 

    发现 c.A()和 c.Parent.A()都只调用到了 Parent 的 B()方法
    有办法可以在 A()方法中调用到 Child 的 B()方法吗

    第 1 条附言    2017-05-03 10:05:43 +08:00
    感谢各位的回复,所以说应该是 go 的语法特性,不能这样使用吧。楼上各位已一一感谢,就不艾特了
    15 条回复    2017-05-03 10:16:13 +08:00
    Kilerd
        1
    Kilerd  
       2017-05-02 16:44:36 +08:00 via iPhone   1
    不可能吧?!
    shadowind
        2
    shadowind  
       2017-05-02 16:59:41 +08:00   2
    go 的嵌套不会重载,所以都是`Parent`的`B()`方法。

    使用`interface`可以解决你的需求。
    x8
        3
    x8  
       2017-05-02 18:15:53 +08:00   1
    加一个方法

    func (c *Child) A() {
    c.B()
    }

    调什么方法得看方法绑定的指针类型
    sumhat
        4
    sumhat  
       2017-05-02 18:32:28 +08:00   1
    Golang 中 Parent 不知道 Child 的存在,一旦调用了 Parent 的方法,之后所有的调用都局限在 Parent 中。
    bianhua
        5
    bianhua  
       2017-05-02 18:38:23 +08:00   1
    @sumhat 其实可以解释的更简单一点:Golang 没有 Override。之所以 c.A()能运行,仅仅是因为这是一种语法糖。实际上 c.A()跟 c.Parent.A()是等价的。
    rrfeng
        6
    rrfeng  
       2017-05-02 18:41:40 +08:00   1
    楼上已经回答的很清楚了。
    不过即使是在支持重载的语言中这个写法也不怎么优雅吧?

    你需要 interface
    zhujinliang
        7
    zhujinliang  
       2017-05-02 18:49:11 +08:00   1
    还有种方法

    package main

    import "fmt"

    type CanB interface {
    B()
    }

    type Parent struct {
    instance CanB
    }

    func (p *Parent) A() {
    p.B()
    }

    func (p *Parent) B() {
    if p.instance != nil {
    p.instance.B()
    return
    }
    fmt.Println("parent.B()")
    }
    func (p *Parent) SetInstance(i interface{}) {
    if inst, ok := i.(CanB); ok {
    p.instance = inst
    }
    }

    type Child struct {
    Parent
    }

    func (c *Child) B() {
    fmt.Println("child.B()")
    }

    func main() {
    p := &Parent{}
    c := &Child{}

    c.SetInstance(c)

    p.A()
    c.A()
    c.Parent.A()
    }
    zhujinliang
        8
    zhujinliang  
       2017-05-02 18:49:39 +08:00   2
    Immortal
        9
    Immortal  
       2017-05-02 19:19:54 +08:00   1
    重载 Child 的 A 方法
    chlid.A()会调用到 child 的 A 方法
    child.parent.A()会调用到 parent 的 A 方法
    jarlyyn
        10
    jarlyyn  
       2017-05-02 19:24:30 +08:00   1
    个人觉得,go 没有 oop ……

    所谓的继承其实就是帮你自动调用嵌入结构的同名函数的语法糖。

    就我的角度来看,大部分的操作 需要一个外部函数 调用 interface 来处理。

    而非写作方法本身。

    也就是 不是 p.A(),c.A()
    而是 A(p),A(c)
    scnace
        11
    scnace  
       2017-05-02 19:31:56 +08:00   1
    2L 正解 贴下实现,顺便贴下实现(不是很喜欢这么写),https://play.golang.org/p/6NcQ45ai8v
    scnace
        12
    scnace  
       2017-05-02 19:32:33 +08:00
    Immortal
        13
    Immortal  
       2017-05-02 19:40:02 +08:00   1
    @jarlyyn 其实原理和你说的是基本一样的 p.A()和 A(p) 记得 go 笔记那本书里有写
    hilow
        14
    hilow  
       2017-05-02 21:15:54 +08:00
    @zhujinliang 厉害了
    croz
        15
    croz  
    OP
       2017-05-03 10:16:13 +08:00
    学习了楼上给出的方法,非常感谢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2541 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 12:11 PVG 20:11 LAX 05:11 JFK 08:11
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86