背景
最近Goに入門したんだけれど、JavaやKotlinなどを主に書いていた自分にとってGoのinterfaceはなかなかしっくり来なかったので調べた。
調べた内容
ダックタイピングとは
Rubyなどの動的型付け言語でよく用いられる型付けの作法。
ダック・タイピング - Wikipedia
もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである。
というのは確かにしっくり来る説明だと思う。
Goのinterfaceがなんでわからなかったか
JavaなどのInterfaceは、自身が基底の型のように扱われることでどのようなクラスであるかを表現する。
一方でGoのInterfaceは満たすべき振る舞いを定義し、その振る舞いを満たすかどうかで制約を表現する。
前者は 定義されるクラスが自分がなんの型の具象か
を文脈とする一方で、後者は 利用したい構造体に期待される振る舞い
を表す文脈のように思える。
どちらでもポリモーフィズムは表現出来るものの、思考の出発点と適用する対象が異なっているためにわからなかった…ような気がする。
なんとなくわかったのでコードを書いてみる
lifetime()
が期待する Life
の振る舞いを満たす Human
を利用する例。
package main import "fmt" func main() { var human = Human{} lifetime(human) } func lifetime(l Life) { l.Birth() l.Die() } type Life interface { Birth() Die() } type Human struct { } func (h Human) Birth() { fmt.Println("うまれた") } func (h Human) Die() { fmt.Println("しにました") }
感想
実装クラスがどのinterfaceに対応しているか明示している言語の方が安心感があるなと思ってしまった。
ダックタイピングの理屈はわかったけど、メリットはいまいち理解できずにいる。
うまくマッチする実装に出会ったら変わるのかなぁ。
参考資料
なぜGoはDuck typingを採用していると言えるのか、データ構造から詳しく解説してみた - Qiita
Go言語でのダックタイピング | MMM公式ブログ