Go
Goでダックタイピングしてみる
Goは静的型付けのコンパイル型言語なので、ダックタイピングのような手法を使いたければ、Rustのトレイト方式やSwiftのプロトコル方式のようにインターフェースを1つ作って、構造体をそのインターフェース型にキャストして関数に投げれば良いのではないかと思える。
しかしGoはインターフェースこそ必要であるものの、キャストしなくても(構造体のまま)関数に投げることができ、関数はそれをインターフェース型として受け取ることができる。
これはGoがStructuralTypingのような型システムを持っていて、下の例でいうとDog, Cat, Mouse各構造体に紐づけているvoice()関数の型がインターフェースAnimalに記述したvoice()関数と同じ(関数のシグネチャが同じ)時に限って、そのままの構造体の型で受け取ることができる仕様になっているためだ。
動的型付け言語の関数やC++の関数テンプレートのように「どんな型でも何でも来い」というわけではないが、この仕組みを持っていることが「Goはダックタイピングができる」と言われる所以だと思う。
ちなみにGoのインターフェースはJavaのインターフェースやRustのトレイトと違って、構造体との依存関係は無い。
つまり構造体への関数実装強制力は無いし、構造体へ関数を紐づけるときにインターフェース名を書く必要も無い。
|