Works by

Ren's blog

@rennnosuke_rk 技術ブログです

【Golang】Go 1.14 の重複するメソッドを持つインターフェース埋め込みの許可

proposal/6977-overlapping-interfaces.md at master · golang/proposal

Go 1.14 より、重複するメソッドを持ったインタフェースの複数埋め込みが可能になった。

インタフェースの埋め込みは、あるインタフェース A を別のインタフェース B 内で宣言することで、A で宣言したメソッドを B でも宣言したことにできる機能。

// on Package io :
// type ReadCloser interface {
//     Reader
//     Closer
// }
import io

type CustomReadCloser interface {
    io.ReadCloser
    isClosed() bool
}

Go1.13 までは、言語仕様としてインタフェースのメソッドには一意性制約があるため、B が A の宣言するメソッドを既に宣言していたり、埋め込んだインタフェース同士が同じメソッドを持つとコンパイルエラーとなっていた。

Go1.14 では「埋め込んだインタフェース同士が同じメソッドを持つ」場合に関してはコンパイルが通る様になる。

例えば、下記のインタフェース埋め込みは Go 1.13 以前は不可能だったが、1.14 より可能になる。

// on Package io :
// type ReadCloser interface {
//     Reader
//     Closer
// }
// type WriteCloser interface {
//     Writer
//     Closer
// }
import io

type ReadWriteCloser interface {
    io.ReadCloser
    io.WriteCloser
}

io.ReadCloserio.WriteCloser は共に Close() メソッドを宣言しているが、Go1.14 ではコンパイルが通る。

ただし、メソッドの名称が同一だがシグネチャが異なる場合、埋め込みは許可されない。

type E1 interface {
    m(x int) bool
}
type E2 interface {
    m(x float32) bool
}
type I  interface {
    E1
    E2
}

議論として、埋め込まれた側のインタフェースが埋め込みインタフェースと同一のメソッドを持つ場合どうするか問題が議論に上っていたが、上記の通りGo の言語仕様のインタフェース一意性の項目

Explicitly declared methods in an interface must remain unique, as before.

と書かれているため、多分許可されないままだと思われる。

参考文献