我有一些示例代码 ,其中我声明一个类型foo
一些方法,其相互调用(比如: foo.get
,这是由称为foo.double
和foo.toString
)。
我有另一种类型, bar
,其中嵌入foo
并重新定义get
。 我不得不重新定义double
和toString
上bar
,这样他们就可以看到bar.get
(而不是只foo.get
),但这些功能的身体基本上等同于原始。
有没有更好的方式来组织这些代码,以避免同时还具有冗余bar
履行相同的接口foo
?
笔记:
- 如上举办的代码工作正常; 它只是难以维持,因为当我去重新定义最初宣布的方法
foo
上嵌入的类型foo
我要仔细检查,看看哪些其他方法foo
调用它,并确保重新定义所有这些了。 它已被证明是很容易不小心错过一个。 - 在其上,这是基于真实的项目有近十类型的嵌入“
foo
”,和一个类似的上各类型间连接的方法数。 - 我可以添加一个接口重要成员为foo包含一个指向嵌入其最外层的结构,并有
foo.double
呼叫f.outermost.get()
代替f.get()
但是这似乎有点浪费,将意味着零个值foo
都无效。 (加上它是唯一可能如果嵌入类型是一个结构。)
在去那里的嵌入 ,但没有多态性 。 如果你在一个结构嵌入型,嵌入型的所有方法得到提升,并将成为该方法集包装结构类型的。 但你不能“越权”的推广方法。 当然,你可以使用相同的名称添加自己的方法,并呼吁通过在包装结构同名的方法调用你的方法,但如果这种方法是从嵌入式叫,不会被分派到你的方法,仍然会调用被定义为嵌入型“原始”的方法。
了解更多关于此这里: 是否脆弱的基类问题转到存在吗? 在这里: 围棋嵌入式结构调用子方法,而不是父类的方法 。
它看起来像你只是想“继承”的double()
和toString()
的方法(这应该被称为String()
中去),但不是get()
方法,从类型到类型及其实施的变化。
所以基本上你应该重构一点。 您的foo
类型都应该有/获取,提供了一个值get()
方法。 您可以通过捕获此getter
接口:
type getter interface {
get() int
}
而foo
实现:
type foo struct {
g getter
}
func (f foo) double() int {
return f.g.get() * 2
}
func (f foo) toString() string {
return fmt.Sprintf("%d", f.g.get())
}
而一个bar
中嵌入型foo
,只提供了“失踪” get()
:
type bar struct {
foo
}
func (b bar) get() int {
return 69
}
用法示例:
b := bar{}
b.foo = foo{g: b}
fmt.Println(b.double())
fmt.Println(b.toString())
输出为预期(尝试在转到操场 ):
138
69
用一个简单的函数值
使用上面的getter
接口是好的,因为它在将来提供了灵活性,如果您需要其他的方法添加到它。
如果是这种情况并非如此,所有你需要的是一个单一的功能,你可以离开了接口,只需使用一个函数值。
这是怎么会是这样的:
type foo struct {
get func() int
}
func (f foo) double() int {
return f.get() * 2
}
func (f foo) toString() string {
return fmt.Sprintf("%d", f.get())
}
type bar struct {
foo
}
func (b bar) get() int {
return 69
}
并使用它:
b := bar{}
b.foo = foo{get: b.get}
fmt.Println(b.double())
fmt.Println(b.toString())
输出是一样的。 试试在转到操场 。
请注意,虽然我们使用的bar.get()
方法( b.get
法值 ),它不是一个要求get()
应该是一个方法。 它可以是一个普通的函数值,或甚至一个函数文本 ,如:
b := bar{foo: foo{get: func() int { return 69 }}}
fmt.Println(b.double())
fmt.Println(b.toString())
试试这一个在去游乐场 。
文章来源: How can I organise this Go code that redefines methods from an embedded type to be less redundant and more maintainable?