2013-03-17 83 views
2

我目前正在与一些Go代码玩耍,并遇到了涉及嵌入,我无法找到一个满意的答案,一个小问题。给定两个类型,其中之一嵌入其他,并且满足的接口,我想的埋入型,以便能够反映在嵌入器的特性,以提供默认的响应,从而使该对象不必定义界面中的所有方法,除非他们想要覆盖。如何嵌入默认的实现中去:是指嵌入型

在下面的玩具示例中,我希望能够定义一个hello()函数,用于处理默认情况,并返回Name(注意,这是一个玩具示例,实际代码更复杂,有用的),而不要求对象显式地定义接口上的所有方法。真正的代码使用反射来占卜对象类型的类名和构造名,目前我打电话基类佣工传入类型的实例,但这并不感到满意。

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

在goplay:

http://play.golang.org/p/ClOOCef9Zb

我很想听到围棋其他解决方案,这类问题(提供其使用嵌入类的属性默认功能)以及作为解决这个特定问题的方法(如果有的话)。到目前为止,唯一的解决方案是:

要求在满足此接口的所有类型上重新定义方法hello(),并放弃拥有提供默认方法的“基本”类 调用嵌入的帮助函数一个指向对象实例的指针,所以类型可以大多为空的方法调用嵌入类型。

如果有完全不同的方法在Go中有价值,并且不试图复制继承模型,那么我会很有兴趣了解它们,到目前为止,这是我唯一一次遗漏继承。 。

回答

2

的方法的接收器是/是指相应的类型T的实例有没有语言支持的方法如何获得大约T t的任何信息被嵌入,说ü在执行T的方法:

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,去支持接口继承和方法重载,所以可能的方式。请注意,在这种情况下,继承是行为的,而不是结构性的。

+1

谢谢。我怀疑这是由于使用继承的语言而导致Go的部分原因 - 我很高兴没有继承,但在这种情况下,它感觉不对。我有一个解决方案,但它并不觉得非常优雅(通过一个* o嵌入式函数满足接口),所以我想知道是否有更好的方法来处理提供的方法,可以反映他们的嵌入类型(例如获取其名称或其他字段)。如果你可以在最后一句话中稍微扩大一点,那将会很好...... – 2013-03-17 12:01:47

+0

@KennyGrant:在适当/不可避免的情况下,最简单的方法可能是在'T'类型中加入一个类似'outer * U'的字段。但坦率地说,重新思考模型通常会摆脱这样的OOP“黑客”;-) – zzzz 2013-03-17 12:29:36

+0

我发布的部分原因是要看看是否有人在此特定情况下重新考虑整个方法的具体建议。我愿意提供建议:)我希望有一些非常简单的东西可以作为响应接口提供默认功能的方式。使用匿名嵌入对我来说工作得很好,因为我不需要关于嵌入结构的信息,但是在少数情况下,我可以... – 2013-03-17 12:53:10

0

为了解决这个问题,我决定抛弃ersatz继承,并指定模型需要在接口中共享的信息(这里缺少字段的自动属性访问器有点烦人,上面的对象必须明确地导出这些以允许任何通过MyInterface引用的人使用它们,即使在接口上定义了Name()字符串,字段Name也是公共的,但不可访问)。然后

该模型在另一封装调用辅助功能,并且提供本身作为参数,其中是有用的,并且因为它符合MyInterface的它可以询问的方式。所以它(和其他MyInterface对象)可以使用他们的公共信息完成复杂的操作,并充当门面。显然,在上面这个简单的例子是毫无意义的,但我想从几个包类型MyInterface的之间共享代码,而现在将这种方法去,而不是嵌入。

所以我的主要东西,正如上面的jnml指出的那样,嵌入对依赖于实例状态的函数中的混合没有用处,并且不是继承层次结构中基类的直接替换。很明显,也许如果你一直与Go一起工作...

相关问题