我怎样才能组织重新定义从嵌入式方法要少多余的,更易于维护这个Go代码?(How can I orga

2019-09-29 04:33发布

我有一些示例代码 ,其中我声明一个类型foo一些方法,其相互调用(比如: foo.get ,这是由称为foo.doublefoo.toString )。

我有另一种类型, bar ,其中嵌入foo并重新定义get 。 我不得不重新定义doubletoStringbar ,这样他们就可以看到bar.get (而不是只foo.get ),但这些功能的身体基本上等同于原始。

有没有更好的方式来组织这些代码,以避免同时还具有冗余bar履行相同的接口foo

笔记:

  • 如上举办的代码工作正常; 它只是难以维持,因为当我去重新定义最初宣布的方法foo上嵌入的类型foo我要仔细检查,看看哪些其他方法foo调用它,并确保重新定义所有这些了。 它已被证明是很容易不小心错过一个。
  • 在其上,这是基于真实的项目有近十类型的嵌入“ foo ”,和一个类似的上各类型间连接的方法数。
  • 我可以添加一个接口重要成员为foo包含一个指向嵌入其最外层的结构,并有foo.double呼叫f.outermost.get()代替f.get()但是这似乎有点浪费,将意味着零个值foo都无效。 (加上它是唯一可能如果嵌入类型是一个结构。)

Answer 1:

在去那里的嵌入 ,但没有多态性 。 如果你在一个结构嵌入型,嵌入型的所有方法得到提升,并将成为该方法集包装结构类型的。 但你不能“越权”的推广方法。 当然,你可以使用相同的名称添加自己的方法,并呼吁通过在包装结构同名的方法调用你的方法,但如果这种方法是从嵌入式叫,不会被分派到你的方法,仍然会调用被定义为嵌入型“原始”的方法。

了解更多关于此这里: 是否脆弱的基类问题转到存在吗? 在这里: 围棋嵌入式结构调用子方法,而不是父类的方法 。

它看起来像你只是想“继承”的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?