TL; DR 请参阅底部的游乐场链接。
我在Manager
结构上定义了包含Context
的方法。 Manager
是版本化的,允许新版本仅定义已更改的函数,如果未重新定义,则自动使用旧版本的函数。
type Context struct { ... }
type Manager1 struct{
Context Context
}
type Manager2 struct {
Manager1
Context Context
}
在Manager2
上调用未在Manager2
上定义的函数时,Context
为零。有没有办法在上下文可用的情况下执行此操作?
这个例子比我能解释的更好地展示了这个问题: http://play.golang.org/p/gFe6GgUKEJ
答案 0 :(得分:3)
您滥用嵌入。问题是,您已经在@Html.ActionLink("New Child", "Create", new { id = item.Id })
上定义了Context
,尽管您已经在每个后续类型上重新定义了Manager1
。在Manager3
中,您需要为其Context
实例设置值。当Hello()
被调用时,它会在Manager2
上定义,并访问它的Context
实例,而该实例没有值。查看此示例以演示http://play.golang.org/p/XebShA9ap4
资金线是:
m3 = Manager3{Manager2: Manager2{Context: Context{Value: "testing3"}}}
如您所见,如果我实例化Manager2
中嵌入的Manager3
实例并设置它的Context
值,则会打印出来。我建议您更改类型,以便Context
仅在Manager1
上定义,然后在初始化类型时使用我的示例中的语法。
编辑:要将评论中讨论的设计改为书面形式,您可以将类型更改为此;
type Context struct {
Value string
}
type Manager1 struct {
Context Context
}
type Manager2 struct {
Manager1
}
type Manager3 struct {
Manager2
}
完全删除Hello()
上Manager2
的实施。然后将composite-literal初始化更新为this;
m1 := Manager1{Context: Context{Value: "testing1"}}
m2 := Manager2{Manager1: Manager1{Context: Context{Value: "testing2"}}}
m3 := Manager3{Manager2: Manager2{Manager1: Manager1{Context: Context{Value: "testing3"}}}}
答案 1 :(得分:2)
你误解了通过嵌入结构调用嵌入式结构的方法:这只是语法糖!
您可以将m3.Manager2.Hello()
缩写为m3.Hello()
,但永远不会在“m3”上调用Hello方法,但始终在嵌入式Manager2
上调用(具有nil Contex)。
嵌入不允许“覆盖方法”。嵌入不是子类化,它只是语法糖。
答案 2 :(得分:0)
您的Manager3
结构包含多个Context
成员 - 您正在设置Manager3.Context
,但打印Manager2.Context
。您可能正在寻找的是从Context
和Manager1
中移除多余的Manager2
成员并以这种方式初始化结构:
var (
m1 = Manager1{Context: Context{Value: "testing1"}}
m2 = Manager2{Manager1: Manager1{Context: Context{Value: "testing2"}}}
m3 = Manager3{Manager2: Manager2{Manager1: Manager1{Context: Context{Value: "testing3"}}}}
)
此处的完整示例:http://play.golang.org/p/13DOYKWN5C
提供访问者或工厂功能可能会使这更好一些。