Snippet: Extend Builtins | The Scala Programming Language
Scalaの特徴的な機能であるImplicit Conversion(暗黙的な型変換)。
Implicit ConversionについてはJJUG CCCのBOFでもScalaについて話されていた水島さんの資料がわかりやすいです。
http://www.coins.tsukuba.ac.jp/~i021216/docs/Scala-implicit-conversion.pdf
package sample.snippet object ExtendBuiltins extends Application { def fact(n: Int): BigInt = { if(n == 0) { 1 } else { fact(n -1) * n } } class Factorizer(n: Int) { def ! = fact(n) } implicit def int2fact(n: Int) = new Factorizer(n) println(new Factorizer(5).!) println(new Factorizer(5) !) println(10 !) // below code is compile error. why?? // println(10.!) println(10!) }
詳細は後で解説するとして、注目は「10!」。
10はもちろんInt型だし、「!」なんてメソッドは定義されていない。
だけどこのコードはコンパイルエラーにも実行時エラーにもならない。
Implicit Conversionを利用しているから。
implicitというキーワードを使ってメソッドを定義してる。それがint2fact。
この引数と戻り値がポイント。引数はIntで戻り値はFactorizer。
つまり、Intにないメソッド呼び出しもこのImplicitにした変換メソッドを検知してFactorizer型に変換し、
Factorizerの「!」を呼び出しているってこと。
変換するたびにインスタンスを生成って勉強会で聞いたような気がする。
だからまるでInt型に階乗を計算するメソッド「!」を定義したかのように使えちゃう。
わからないこと
メソッド呼び出しなんで
- println(10!)
- println(10 !)
- println(10.!)
のどれもいけると思ったけど、println(10.!)はコンパイルエラーになってしまう。。。
なんでだろう??理解を誤っているのかな。。。