例えば container/list の拡張を考える。
シンプルにstructの埋め込みで実装してみた場合、
// https://play.golang.org/p/2-eVlADzDu
package main
import (
"fmt"
"container/list"
)
type Element struct {
*list.Element
}
func enhanceElement(e *list.Element) *Element {
return &Element{e}
}
func (e *Element) Advance(n int) *Element {
if n == 0 {
return e
}
forward := n > 0
if !forward {
n = -n
}
r := e
for i := 0; i < n; i++ {
if forward {
r = enhanceElement(r.Next())
} else {
r = enhanceElement(r.Prev())
}
if r == nil {
return nil
}
}
return r
}
func main() {
l := list.New()
l.PushBack(1)
l.PushBack(2)
l.PushBack(3)
l.PushBack(4)
l.PushBack(5)
e := enhanceElement(l.Front()).Advance(3)
fmt.Println(e.Value)
e = enhanceElement(l.Back()).Advance(-3)
fmt.Println(e.Value)
}
このような感じにすることで、一応動くものは作れるが、埋め込み元のメソッドを呼び出す場合、
enhanceElement(l.Front()).Next().Advance()
とはできず、
enhanceElement(enhanceElement(l.Front()).Next()).Advance()
とする必要があり、イケてない。
…わけであるが、良いアイデアが浮かばなかったので諦めた。。。
よくよく考えたら、普通のOOP言語でもupcastが必要なシナリオだった。
素直に
func AdvanceElement(e *list.Element, n int) *list.Element {
// ...
}
とするか、あるいは操作機能専用と割りきってラップstructを作るのが、筋が良さそうだろうか。