【问题标题】:Proper way to call overloaded method of embedded type in Go在 Go 中调用嵌入类型的重载方法的正确方法
【发布时间】:2015-04-29 21:40:46
【问题描述】:

我有一个界面:

 package pkg
 type BaseInterface interface {
     func Nifty() bool
     func Other1() 
     func Other2()
     ...
     func Other34123()
 }

以及实现它的结构:

 package pkg
 type Impl struct {}
 func (Impl) Nifty() bool { ... }

然后出现了另一个想要嵌入第一个并自己做 Nifty() 的结构:

 package myOtherPackage
 import "pkg"
 type ImplToo struct {
     *pkg.Impl
 }
 func (it ImplToo) Nifty() bool { ... something else ... }

这有点像 OOP 语言中方法覆盖的类继承。我想知道如何做 implToo.super().Nifty() 的等价物——也就是说,从 ImplToo Nifty() 实现中,调用 pkg.Impl Nifty() 实现。

it 上使用的正确转换是什么,以便我可以完成此操作?我尝试的一切要么在 ImplToo 的 Nifty() 上产生无限递归,要么产生一些编译器错误,例如:

invalid type assertion: (&it).(BaseInterface) (non-interface type *it on left)

...或许多变体。

【问题讨论】:

  • 你试过it.Impl.Nifty()吗?
  • 我做到了。问题是我的实际“Impl”实际上被命名为“name.withADot”,所以解析告诉我相当于(type ImplToo has no field or method name)这似乎让我认为“好的,那么parens”,但它。(name.withADot) .nifty被解析为接口转换,返回non-interface type on left错误。
  • 我不明白。标识符不能包含点字符。请发布您的代码。
  • 但是类型可以,因为它们是由包名限定的。点既是选择器又是包限定符。我在上面进行了编辑以反映我在说什么。 (而当你嵌入时,/type 名称就是字段名称/。那么如何选择呢?等等)

标签: types go embedding


【解决方案1】:

你正在寻找;

 type ImplToo struct {
     pkg.Impl
 }

func (it ImplToo) Nifty() bool { return it.Impl.Nifty() }

您对指针的使用不一致,这可能是(不是积极的)问题的一部分。如果你想让嵌入类型成为指针,那么你的方法接收类型也是指针,以避免这个问题。

如果您想显式使用嵌入类型中的方法,请使用通常具有属性名称的类型来引用它。

【讨论】:

  • 请注意我使用上面的包前缀进行的编辑。您的 ImplToo 不是结构的有效声明,因为未定义 Impl。它是本地包中的 pkg.Impl 。如果是 pkg.Impl,我得到(type ImplToo has no field or method name pkg)
  • @BadZen 好的,我解决了您对包裹的担忧。它不会影响 Nifty 的主体,只会影响 stucts 声明。
  • 创建一个没有嵌入的新类型无济于事 - 类型接收器的某些函数 /not/ 以这种方式“重载”,我希望能够从相同的表达。您基本上是在说“不要使用嵌入,而是编写所有内容”。这很好,直到我需要将我的类型传递给一些已经存在的需要 BaseInterface 的函数。还可以考虑调用 myImpl.In.A.Really.Long.Chain.Of.Subclasses()....
  • 换一种说法:ImplNotEmbed / 甚至不会编译 / 除非我提供将接口的其他方法映射到它的 Impl 的“管道代码”。这对于大型接口来说是不可接受的......
  • @BadZen ImplNotEmbed 只是应该向您展示如何访问嵌入式类型与非嵌入式属性的区别。这里没有组合发生。就像在 OOP 中一样,如果你想覆盖派生类中的方法并使用基类实现,你必须明确声明......如果你没有在 ImplToo 中覆盖 Nifty,你总是可以直接从实例调用Nifty()...它被称为“ImplNotEmbed”,因为我没有使用嵌入...
【解决方案2】:

@evanmcdonnal 说了什么。你的 Nifty 要么需要指针,要么不需要指针。如果您嵌入指向pkg.Impl 的指针,那么您的 Nifty 函数需要接受一个结构指针。如果你的 Nifty 函数不接受指针,那么你的嵌入类型不应该是指针。

这是一个有效的嵌入式指针。

·> cat main.go

package main

import (
    "cs/pkg"
    "fmt"
)

type ImplToo struct {
    *pkg.Impl
}

func (it *ImplToo) Nifty() bool {
    fmt.Printf("Impl.Nifty() is %t\n", it.Impl.Nifty())
    return false
}

func main() {
    i := new(ImplToo)
    fmt.Println(i.Nifty())
}

·> cat cs/pkg/test.go

package pkg

type BaseInterface interface {
    Nifty() bool
}

type Impl struct{}

func (i *Impl) Nifty() bool {
    return true
}

输出:

Impl.Nifty() is true
false

【讨论】:

  • 我认为现在在嵌入而不是接收器中使用指针时工作正常。这是否意味着有一个额外的接收接口副本正在进行?当两者都是指针时它不会编译:ImplToo does not implement pkg.BaseInterface (Nifty method has pointer receiver)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多