Go の interface は Java, PHP といった言語と比べて使い方が異なる。例えば, 独自例外の定義には, error interface の実装が必要。
とてもシンプルなインターフェースで実装例は以下の通り
package hoge
type MyError struct {
Id int
Name string
}
func (e *MyError) Error() string {
return fmt.Sprintf("id: %s name: %s")
}
var undefinedError := &MyError{Id: 1, Name: "undefined"}
// 型として error を返すメソッドの中で実際 error が実装されていることを確認できる
func hoge() error {
return undefinedError
}
こんな感じで実装する側では interface にあるメソッドを実装するだけでいい。自身で定義する場合でも同じ。
Go は本家がベスプラ(推奨レベル)を公開してる。タイトルに含まれる「Accept Interfaces, Return structs」は, その中の一つ。
先ほど紹介した error interface は, go 側では「エラーはこのような振る舞いをする。どのように実装するかはあなた次第だ。」となっている。これに従うよう「扱う側でインターフェース。実装する側は実物。」を定義したほうがいいぞ。という話。
シンプルな例を出す。packge foo が Hoge interface を扱う例。
package foo
import "fmt"
type Hoge interface {
HogeMethod() string
}
func Exec(h Hoge) {
fmt.Println(h.HogeMethod())
}
この場合, 単に string を返す HogeMethod を持つなんかを実装すればいい。
package hoge
type Hoge struct{}
func New() *Hoge {
return &Hoge{}
}
func (h *Hoge) HogeMethod() string {
return "hoge method."
}
package main
import (
"fmt"
"github.com/somen440/zatsu/golang/interface/foo"
"github.com/somen440/zatsu/golang/interface/hoge"
)
func main() {
fmt.Println("interface test --")
foo.Exec(hoge.New())
}
結果は以下の通り, 読み込める。
zatsu/golang/interface on master [$?] via 🐹 v1.14.4
❯ go run .
interface test --
hoge method.