ダックタイピング
Think IT の記事を参考に、Scala でのダックタイピングを試してみた。
http://www.thinkit.co.jp/cert/article/0711/4/3/3.htm
object Sample { def foo[T](x: T {def bar: Boolean}): Boolean = x.bar def main(args: Array[String]): Unit = { println(foo(new { def bar = true })) } }
ちゃんとコンパイル&実行できた。
foo の引数に渡すオブジェクトには、bar という関数さえありさえすれば良い。
def foo[T](x: T {def bar: Boolean})
呼び出し側では、即席で作ったオブジェクトを渡してみた。
foo(new { def bar = true })
Java と比べると、ものすごくシンプルに記述できる。
javap で foo のメソッドシグネチャを見てみると、その引数は Object なので型チェックはコンパイル時のみ有効なのだと思う。
public final class ducktyping.Sample$ extends java.lang.Object implements scala.ScalaObject{ public static final ducktyping.Sample$ MODULE$; private static java.lang.Class reflClass$Cache1; private static java.lang.reflect.Method reflMethod$Cache1; public static {}; public ducktyping.Sample$(); public void main(java.lang.String[]); public boolean foo(java.lang.Object); public int $tag() throws java.rmi.RemoteException; public static java.lang.reflect.Method reflMethod$Method1(java.lang.Class); }
ってことは、おそらく bar メソッドはリフレクションで呼び出しているんだろうと推測。
あまり多用すると遅いかもしれない。