post Image
インタフェースは型名を公開しなくても実装できる #golang

インタフェースの実装

Goのインタフェースは、明示的に実装する必要がありません。
インタフェースが定義しているメソッドリストとその型が持つメソッドのリストが一致すれば実装していることになります。
インタフェースについて詳しく知りたい方は、以下の記事にまとめていますので参考にしてください。

同じメソッドリストをもつインタフェース

上記のような特徴からインタフェースは、typeで付けられた型名はさほど重要ではなく、どのメソッドを持っているかが重要になってきます。
以下のコードを見ると、Str型が3種類のインタフェースを実装していることがわかります。
それぞれ、外部のパッケージで定義された型、関数内で定義された型、型リテラルです。
名前は違いますが、どれも同じメソッドリストを持つインタフェースです。

関数内でtypeを使って型定義を行っていることに驚く方がいるかもしれませんが、関数内だけで有効な型を作りたい場合はこの方法が使えます。
また、型リテラルは型そのものを記述したもので、[]intなどもそれにあたります。
typeは型リテラルや名前の付いている既存の型に新たに名前をつけているだけだということに気づくと思います。

なお、あるインタフェース型の変数として_に代入する方法は、ある型が特定のインタフェースを実装しているかコンパイル時にチェックする方法としてイディオムになっています。
詳しくは、Effective Goを見ると良いと思います。

Go Playgroundで動かす

package main

import (
    "fmt"
)

type Str string

func (s Str) String() string {
    return string(s)
}

func main() {
    var s Str = "hoge"

    var _ fmt.Stringer = s

    type MyStringer interface {
        String() string
    }
    var _ MyStringer = s

    var _ interface {
        String() string
    } = s
}

インタフェースの型名を公開せずに利用する

pkg/errorsの実装を見ると、一見、見慣れないコードを見つけることができます。
Cause関数内で定義されているcauser型は、メソッド内で定義された型であるため、関数外(もちろん、外部パッケージも含む)から型名を知ることができません。
しかし、上述の通りインタフェースは、定義しているメソッドリストが重要なので型名を公開しなくても、そのインタフェースを実装しているかのチェックには使えます。
インタフェース型を引数に受け取ったり、戻り値として返す場合は、名前を付けて公開した方が便利なので、大文字で始まる名前をつけて関数外で定義するべきでしょう。
しかし、pkg/errorsパッケージでは、関数内でCauseメソッドを実装しているエラーかどうかを知りたいだけなので、インタフェース型リテラルに名前をつけて公開する必要がありません。

pkg/errorsから引用

func Cause(err error) error {
    type causer interface {
        Cause() error
    }

    for err != nil {
        cause, ok := err.(causer)
        if !ok {
            break
        }
        err = cause.Cause()
    }
    return err
}

なお、上記のコードは以下のようにも書けます。

func Cause(err error) error {
    for err != nil {
        cause, ok := err.(interface { Cause() error })
        if !ok {
            break
        }
        err = cause.Cause()
    }
    return err
}

まとめ

一見、pkg/errorsパッケージのコードは不思議ですが、よくよく考えると理にかなっています。
構造体や他の型の型だと外部パッケージに公開するには、大文字で始まる型名をつけて定義する必要がありますが、インタフェースはその制約はありません。
こういう使い方ができる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

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