调用嵌入结构体的接口方法时,不丢失接收器的类型信息。

huangapple go评论81阅读模式
英文:

Calling embeded struct's interface method without losing type information on the receiver

问题

以下是翻译好的内容:

以下代码失败了,因为在使用B.Assign(A)之后,B的具体类型信息丢失了(至少我认为在这里出错了):

package main

import "fmt"

type Methods interface {
    Method()
    Assign(Methods)
    Set(Methods)
}

type Parent struct {
    Methods
    assigned Methods
}

type ChildA struct {
    Parent
}

type ChildB struct {
    Parent
    msg string
}

func (this *Parent) Assign(other Methods) {
    // 这里有一些其他的逻辑
    other.Set(this)
}

func (this *Parent) Set(other Methods) {
    this.assigned = other
}

func (c *ChildA) Method() {
    fmt.Println("I'm child A")
}

func (c *ChildB) Method() {
    fmt.Println("I'm child B, and I approve this message:", c.msg)
}

func main() {
    A := new(ChildA)
    B := new(ChildB)
    B.msg = "my message"

    B.Assign(A)
    A.assigned.Method()
}

现在,为了避免这个问题,我需要创建另一个方法,它与Parent.Assign()具有完全相同的定义,但是接收者不同:

func (this *Parent) Assign(other Methods) {
    // 这里有一些其他的逻辑
    other.Set(this)
}

func (this *ChildB) Assign(other Methods) {
    // 与上面的方法相同
    other.Set(this)
}

这样做相当丑陋。有没有一种方法可以在从嵌入结构体Parent调用方法时保留关于B类型的信息,而不需要重复代码呢?

英文:

The following code fails, because after using B.Assign(A), the information on the specific type of B is lost (at least that's what I think goes wrong here):

package main

import "fmt"

type Methods interface {
	Method()
	Assign(Methods)
	Set(Methods)
}

type Parent struct {
	Methods
	assigned Methods
}

type ChildA struct {
	Parent
}

type ChildB struct {
	Parent
	msg string
}

func (this *Parent) Assign(other Methods) {
    //Some other logic here
	other.Set(this)
}

func (this *Parent) Set(other Methods) {
	this.assigned = other
}

func (c *ChildA) Method() {
	fmt.Println("I'm child A")
}

func (c *ChildB) Method() {
	fmt.Println("I'm child B, and I approve this message:", c.msg)
}

func main() {
	A := new(ChildA)
	B := new(ChildB)
	B.msg = "my message"

	B.Assign(A)
	A.assigned.Method()

}

Now, in order to avoid this, I would have to make another method, that has exactly the same definition as Parent.Assign(), but different receiver:

func (this *Parent) Assign(other Methods) {
    //Some other logic here
    other.Set(this)                        
}                                          
                                           
func (this *ChildB) Assign(other Methods) {
    //Same as above
    other.Set(this)                        
}                                          

This is rather ugly. Is there a way to preserve the information about B's type when calling the method from it's embedded struct Parent, without duplicating the code?

答案1

得分: 4

在调用嵌入结构体 Parent 中的方法时,有没有一种方法可以保留关于 B 类型的信息,而不需要重复代码?

没有。当你调用嵌入方法时,它是通过指向嵌入结构体的指针进行调用的。

不幸的是,尽管一开始看起来很有吸引力,但嵌入对象并不能使 Go 成为一种面向对象的语言。

你可能最好只使用一个带有函数指针实现的类型。

英文:

> Is there a way to preserve the information about B's type when calling the method from it's embedded struct Parent, without duplicating the code?

No. When you call the embedded method, it is called with a pointer to the embedded struct.

Unfortunately as attractive as it first seems, embedded objects don't make Go into an object oriented language.

You might be better off just having one type with function pointers for the implementation.

huangapple
  • 本文由 发表于 2017年5月2日 21:36:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/43739330.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定