我目前正在研究一些 go 代码,遇到了一个涉及嵌入的小问题,我找不到满意的答案。给定两种类型,其中一种嵌入另一种,并且满足接口(interface),我希望嵌入类型能够反射(reflect)嵌入器的属性以提供默认响应,以便对象不必定义接口(interface)中的所有方法,除非它们想要重写。
在下面的玩具示例中,我希望能够在嵌入式上定义一个 hello() 函数,它处理默认情况并仅返回名称(注意,这是一个玩具示例,真正的代码更加复杂和有用),而不要求对象显式定义接口(interface)上的所有方法。真正的代码使用反射来预测对象类型的类名和构造名称,目前我正在调用传入类型实例的基类帮助程序,但这并不令人满意。
package main
type MyInterface interface {
hello() string
//...
}
type Embedded struct {
}
func (e *Embedded) hello() string {
name := "none"
// Would like to be able to return name of object here *if* embedded
// What's the best approach to tackle this?
return name
}
type Object struct {
*Embedded
Name string
}
/*
// Would like an *optional* override, with default being embedded somehow replying with data from Object
func (o *Object) hello() string {
return o.Name
}
*/
func main() {
o := &Object{Name:"My Object Name"}
println("Hello world",o.hello())
}
在播放时:
http://play.golang.org/p/ClOOCef9Zb
我有兴趣了解 Go to this type of issues 中的其他解决方案(提供使用嵌入类的属性的默认函数)以及针对此特定问题的解决方案(如果有的话)。到目前为止我唯一的解决方案是:
需要在满足此接口(interface)的所有类型上重新定义方法 hello(),并放弃提供默认方法的“基”类 使用指向对象实例的指针调用嵌入式辅助函数,因此类型可以具有调用嵌入式类型的大部分空方法。
如果有完全不同的方法在 Go 中很有值(value)并且不尝试复制继承模型,我有兴趣听到它们,到目前为止这是我在继承中错过的唯一一次......
最佳答案
方法的接收者是/,指的是相应类型 T 的实例。没有语言支持的方法如何获取有关 T 嵌入的任何信息,例如在执行 T 的方法时 U :
type (
T foo
U struct {
t T
f baz
}
)
func bar() {
var t T
var u U
t.foo()
u.t.foo()
}
func (t T) foo() {} // t might be or be not embeded in u
func (t *T) qux() {} // *t might be or be not embeded in u
您可能正在尝试使用结构继承。这是不支持的。通过嵌入来组合类型,但这与类层次结构不同。
OTOH,Go 接口(interface)支持继承和方法重写,所以这可能就是这样。请注意,在这种情况下,继承是行为性的,而不是结构性的。
关于reflection - 如何在 go 中嵌入默认实现并引用嵌入类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15460357/