post Image
インタフェースを埋込む #golang

本当はGo月Go日に書きたかったけど、ビール飲んで寝てしまったの今日(Go月6日)になりました。

Goのインタフェースは、明示的に実装する必要がなく、インタフェースが定義するメソッドリストをその型が持っていれば、そのインタフェースとして振る舞えます。
構造体に埋め込んだ型が持つメソッドについても、埋込み先の構造体のメソッドの一部としてみなすことができるため、インタフェースの実装の頭数に入れることができます。
インタフェースの実装と埋込みの関係についてはインタフェースの実装パターンという記事に詳しく書いているのでそちらを参考にしてください。

さて、埋込みによって構造体にインタフェース実装させるパターンは思ったよりも使えます。なぜなら、埋込みは単なる匿名フィールドに対して、インタフェースは実装を隠し、型を抽象化ができるからです。このパターンは、共通部分を抜き出して、それを複数の型で使う場合に非常に便利です。

共通部分を抜き出す場合、構造体の埋め込みを使いたくなります。以下のように*fugaFugaに埋め込んだ場合、Fuga*fugaのメソッドをまるで自分のメソッドのように呼び出すことができます。しかし、単なる匿名フィールドのメソッドを呼び出していることには変わりません。また、これらの型はあくまで別の型なので、*fuga型の変数に*Fuga型の値を入れることはできません。

type fuga struct {
}

func (_ *fuga) Method() {
    fmt.Println("hello")
}

type Fuga struct {
    *fuga
}

func NewFuga() *Fuga {
    return &Fuga{&fuga{}}
}

func main() {
    f := NewFuga()
    // あくまで f.fuga.Method() と同じ
    f.Method()  
    var _ *fuga = f // コンパイルエラー
}

しかし、インタフェースはメソッドリストさえ一致していれば、そのインタフェースとして振る舞うことができます。例えば、以下のようにインタフェースを作って埋め込んでみます。

type Hoge interface {
    Method()
}

type fuga struct {
}

func (_ *fuga) Method() {
    fmt.Println("hello")
}

type Fuga struct {
    Hoge
}

func NewFuga() *Fuga {
    return &Fuga{&fuga{}}
}

func main() {
    f := NewFuga()
    f.Method()  
    var _ Hoge = f // OK
}

こうすることにより、*Fuga型はHoge型としても振る舞うことができるようになりました。Hogeインタフェースを埋め込んだ構造体が複数ある場合は、Hoge型としてまとめて扱うことができます。

普段は汎用的なインタフェース型で持っておき、必要な場合に型アサーションで実行時にインタフェースを実装しているかチェックすることもできます。

var f interface{} = NewFuga()
if h, ok := f.(Hoge); ok {
    h.Method()
}

先ほどの例だと、Hoge型が公開されてしまっているので、埋め込んだとしてもFuga.Hogeが外部パッケージから変更されてしまう可能性があります。

f := NewFuga()
f.Hoge = NewFuga() // 匿名フィールドでも上書きできる

そこで、Hogeインタフェースをリネームしただけのhoge型をつくって、こちらを埋め込みましょう。

type Hoge interface {
    Method()
}

// この型は外部に公開されない
type hoge Hoge

type fuga struct {
}

func (_ *fuga) Method() {
    fmt.Println("hello")
}

type Fuga struct {
    hoge
}

func NewFuga() *Fuga {
    return &Fuga{&fuga{}}
}

func main() {
    f := NewFuga()
    f.Method()
}

こうすると、hoge型の匿名フィールドは外部のパッケージに公開されず変更できなくなります。

Goのインタフェースは、シンプルで強力なので使い方次第では面白いことができます。今回紹介した、インタフェースを構造体に埋め込むパターンを使えば、構造体をインタフェースでデコレートしていき、必要な時に特定のインタフェースとして振るまわせることができます。


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。