了解嵌入Go

Her*_*nan 1 embedding go subclassing

我正在尝试了解Google Go的嵌入机制(作为子类化的替代方法).下面是一个简单的程序,总结了我的方法问题:

package main

import "fmt"

type Person struct {
    Name string
}

func (p *Person) Talk() {
    fmt.Println("Hi, my name is Person")
}

func (p *Person) TalkVia() {
    fmt.Println("TalkVia ->")
    p.Talk()
}

type Android struct {
    Person
}

func (p *Android) Talk() {
    fmt.Println("Hi, my name is Android")
}

func main() {
    fmt.Println("Person")
    p := new(Person)
    p.Talk()
    p.TalkVia()

    fmt.Println("Android")
    a := new(Android)
    a.Talk()
    a.TalkVia()
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Person
Hi, my name is Person
TalkVia ->
Hi, my name is Person
Android
Hi, my name is Android
TalkVia ->
Hi, my name is Person
Run Code Online (Sandbox Code Playgroud)

但如果我是子类(用另一种语言),输出将是:

Person
Hi, my name is Person
TalkVia ->
Hi, my name is Person
Android
Hi, my name is Android
TalkVia ->
Hi, my name is Android
Run Code Online (Sandbox Code Playgroud)

有没有办法用google go embedding(不是接口)来实现这最后的输出?

Lin*_*ope 6

不.嵌入是一种单向的方式.嵌入有点过于独特,不能简单地称之为"语法糖" - 它可以用来满足接口.Android应该满足界面

type TalkViaer interface {
    TalkVia()
}
Run Code Online (Sandbox Code Playgroud)

因为它嵌入了一个人.但是,从本质上讲,您必须记住嵌入只是一种非常聪明的方式来访问struct的成员.没有更多或更少.当p传递给TalkVia它时,获得一个人,并且由于该人没有其所有者的概念,它将无法引用其所有者.

您可以通过保留一些所有者变量来解决此问题Person,但嵌入不是继承.根本没有关于"超级"或"扩展者"或类似内容的概念.这只是为结构提供某种方法集的一种非常方便的方法.


编辑:也许还有一点解释.但只是一点点.

type Android struct {
    P person
}
Run Code Online (Sandbox Code Playgroud)

我们都同意,如果我这样做a := Android{},那么a.P.TalkVia()就不会调用Android的任何方法,对吗?即使那是Java或C++,也没有意义,因为它是一个成员.

嵌入仍然只是一个成员.它只是Android拥有的一块数据,不多也不少.在语法层面,它将所有方法赋予Android,但它仍然只是一个成员,你无法改变它.