在Go语言中调用嵌入类型的重载方法的正确方式是什么?

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

Proper way to call overloaded method of embedded type in Go

问题

我有一个接口:

package pkg

type BaseInterface interface {
    Nifty() bool
    Other1()
    Other2()
    ...
    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 ... }

这有点像面向对象语言中的类继承和方法重写。我想知道如何在ImplTooNifty()实现中调用pkg.ImplNifty()实现,类似于implToo.super().Nifty()

我应该如何正确转换it,以实现这个目标?我尝试的每一种方法都会导致ImplTooNifty()方法无限递归,或者出现一些编译器错误,例如:

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

... 或者类似的错误变体。

英文:

I have an interface:

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

and a struct that implements it:

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

Then along comes another struct which wants to embed the first and do it's own Nifty():

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

This is sort of like class inheretance with method override in an OOP language. I want to know how to do the equivalent of implToo.super().Nifty() - that is, from the ImplToo Nifty() implementation, call the pkg.Impl Nifty() implementation.

What is the proper conversion to use on it so that I can accomplish this? Everything I try yields either unbounded recursion on ImplToo's Nifty(), or some compiler error such as:

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

... or many variations on that.

答案1

得分: 1

你正在寻找的是:

type ImplToo struct {
    pkg.Impl
}

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

你对指针的使用不一致,这可能是你的问题的一部分(不确定)。如果你想将嵌入类型设置为指针,那么为了避免这个问题,你的方法接收类型也应该是指针。

如果你想显式地使用嵌入类型中的方法,你可以使用类型来引用它,就像你通常会使用属性名一样。

英文:

You're looking for;

 type ImplToo struct {
     pkg.Impl
 }

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

Your use of pointers isn't consistent which is probably (not positive) part of your problem. If you want to make the embedded type a pointer then make your methods receiving type a pointer as well to avoid this problem.

If you want to explicitly use a method in the embedded type you reference it using the type where you would normally have a property name.

答案2

得分: 1

@evanmcdonnal说的没错。你的Nifty函数要么需要接受一个指针,要么不需要。如果你将指针嵌入到pkg.Impl中,那么你的Nifty函数就需要接受一个结构体指针。如果你的Nifty函数不接受指针,那么你嵌入的类型也不应该是指针。

下面是一个有效的嵌入指针的示例:

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())
}
package pkg

type BaseInterface interface {
	Nifty() bool
}

type Impl struct{}

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

输出结果:

Impl.Nifty() is true
false
英文:

What @evanmcdonnal said. Your Nifty either need to take a pointer or not. If you embed the pointer to pkg.Impl then your Nifty function needs to accept a struct pointer. If your Nifty function doesn't take a pointer then your embeded type should not be a pointer.

Here is an embedded pointer that works.

·> 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
}

Output:

Impl.Nifty() is true
false

huangapple
  • 本文由 发表于 2015年4月30日 05:40:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/29955093.html
匿名

发表评论

匿名网友

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

确定