Golang Cafe #44 まとめ

2014/08/24に開催された「Golang Cafe #44」についてのまとめです。


今回は「インタフェースの実装パターン」を読み進めました。
Go言語を一通り勉強した方なら目新しいものはあまりないかもしれませんが、ハマリどころや、気をつけなくてはならないポイントがまとめられています。
(サンプルはスライド内のものを参考にさせていただいてます)


type宣言で既存の型を再定義、拡張することができます。
C#の拡張メソッドのような感じで、あたかもint型にStringメソッドを追加したように振舞えます。

type Hex int;

func (h Hex) doSomething() { }


type宣言で関数型にも名前を付けることができます。

type HandlerFunc func(w ResponseWriter, r *Request)

func (h *HandlerFunc) doSomething() { }


Go言語でのinterface宣言ではメソッドしか宣言できません。C#のようにプロパティを宣言することはできません。
interfaceを実装する側は、implementや:などで明示的にinterfaceの実装を宣言する必要はありません。
逆に言うと、明示的な宣言がないので、interfaceが実装されていることに気が付きにくいです。

type Hex int;

func (h Hex) String() string { return "some" }

このサンプルはStringerインターフェースを実装していることになります。
typeで宣言された関数型も同じです。


Go言語では継承はサポートされていませんが、構造体の匿名フィールドとして別の型(構造体)を埋め込むことで、継承に”似た”振る舞いをすることができます。

type Name struct {
    FirstName  string
    FamilyName string
}

func (n Name) String() {
    fmt.Printf("%s %s\n", n.FirstName, n.FamilyName)
}

type Person struct {
    Name
    Age int
}

func main() {
    p := Person { Name{ "Taro", "Yamada" }, 20 }

    p.String()
    // p.Name.String() と同じ
}

ただ複数の型を埋め込んだ場合、両方の型に同じ名前のメソッドが存在している場合は、明示的に呼び出す必要があります。
埋め込んだ型があるinterfaceを実装している場合、埋め込み先の方もinterfaceを実装したことになります。


複数の型を埋め込んだ場合、複数の型に存在するメソッドを合わせてinterfaceに宣言されているメソッドを満たせば、埋め込み先の方もinterfaceを実装したことになります。


埋め込み先はinterfaceで宣言しておき、実行時にinterfaceを実装した型を代入することもできます。


「知らない間に実装されている」というのに気づくようになれば、気にせず使えるようになるのではないかと思います。
ただ通常の型のように単純なキャストができない点だけ気をつけなくてはなりません。