Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reflection 如何在go&;中嵌入默认实现;参考嵌入类型_Reflection_Go_Composition - Fatal编程技术网

Reflection 如何在go&;中嵌入默认实现;参考嵌入类型

Reflection 如何在go&;中嵌入默认实现;参考嵌入类型,reflection,go,composition,Reflection,Go,Composition,我目前正在玩一些围棋代码,遇到了一个涉及嵌入的小问题,我找不到满意的答案。给定两种类型,其中一种嵌入另一种,并且满足一个接口,我希望嵌入类型能够反映嵌入程序的属性,以便提供默认响应,这样对象就不必定义接口中的所有方法,除非它们想要重写 在下面的玩具示例中,我希望能够在embedded上定义一个hello()func,它处理默认情况并只返回Name(注意,这是一个玩具示例,实际代码更复杂、更有用),而不需要对象显式定义接口上的所有方法。真正的代码使用反射来判断对象类型的类名和构造名,目前我正在调用

我目前正在玩一些围棋代码,遇到了一个涉及嵌入的小问题,我找不到满意的答案。给定两种类型,其中一种嵌入另一种,并且满足一个接口,我希望嵌入类型能够反映嵌入程序的属性,以便提供默认响应,这样对象就不必定义接口中的所有方法,除非它们想要重写

在下面的玩具示例中,我希望能够在embedded上定义一个hello()func,它处理默认情况并只返回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:

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

需要在满足此接口的所有类型上重新定义方法hello(),并放弃使用提供默认方法的“基类” 使用指向对象实例的指针调用嵌入式帮助器函数,因此类型可以有调用嵌入式类型的大部分空方法


如果有完全不同的方法在Go中很有价值,并且不尝试复制继承模型,我很想听听它们,到目前为止,这是我在继承中错过的唯一一次…

一个方法的接收者是A/引用了相应类型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接口支持继承和方法重写,因此可能就是这样。请注意,在这种情况下,继承是行为的,而不是结构的。

为了解决这个问题,我决定放弃ersatz继承,并指定模型需要在接口中共享的信息(这里缺少字段的自动属性访问器有点烦人,上面的对象必须显式导出这些属性,以允许任何传递MyInterface ref的人使用它们,字段名是公共的,但即使在接口上定义了Name()字符串,也无法访问)

然后,该模型调用另一个包中的helper函数,并将自身作为有用的参数提供,并且当它符合MyInterface时,可以通过这种方式进行查询可以使用公共信息完成复杂的操作并充当门面。显然,在上面的简单示例中,这是没有意义的,但我想在几个MyInterface类型之间共享包中的代码,现在将采用这种方法,而不是嵌入


因此,正如上面jnml所指出的,我在这里的主要收获是嵌入对于混合依赖实例状态的函数没有用处,也不是继承层次结构中基类的直接替代品。如果您已经使用Go一段时间了,很明显…

谢谢。我怀疑这部分是由于从使用继承的语言开始,我很乐意不使用继承,但在这种情况下,我觉得它不合适。我有一个解决方案,但它感觉不太优雅(将*o传递给满足接口的嵌入式类型函数),所以我想知道是否有更好的方法来处理提供的方法,这些方法可以反映它们的嵌入类型(例如获取其名称或其他字段)。如果你能稍微扩展一下你的最后一句话,那就太好了…@KennyGrant:可能最简单的方法,在适当/不可避免的情况下,就是在type
T
中包含一个类似
outer*U
的字段。但是坦率地说,重新思考模型通常会摆脱这种OOP“hacks”;-)我发帖的部分原因是想看看是否有人有具体的建议,可以在这个特殊的例子中重新思考整个方法。我愿意接受建议:)我希望有一种非常简单的方法,可以提供默认函数来响应接口。在我不需要嵌入结构的信息的情况下,使用anon嵌入对我来说很好,但在少数情况下我需要。。。