コップ本読みながら、Scala入門してる。今は第05章の基本型と演算子を読んでる。
Scalaの演算子はすべてメソッド呼び出しらしい。分かりやすくて良い。
例えば
val x = 1 + 1
は
val x = (1).+(2)
と同じらしい。分かりやすい。
単項演算子みたいなのもあると思うのですが、これはunary_hogeみたいなのにマッピングされるみたい。つまり
val x = -1
は
val x = (1).unary_-()
と同一って感じっぽい。分かりやすい。
ちなみにすべてのメソッドは中置演算子のようにできるみたい。例えばStringのindexOfは単なるメソッドだけど、中置演算子として書ける。
val s = "Hello, world!" s indexOf 'o'
これを利用することで、for文で使ってたtoがなぜああいうふうに使えるか分かる。
for (i <- 1 to 10) { println(i) }
これは
for (i <- (1).to(10)) { println(i) }
となって、単にtoメソッドが呼ばれているだけみたい。なるほど。
toの実装を見るために、実際にscalaのコードを見に行ってみる。https://github.com/scala/scala
まずIntはどのへんにあるかなと思ったら、https://github.com/scala/scala/blob/2.11.x/src/library/scala/Int.scala にあった。これはabstract classっぽいので、実際の実装はあんまりなかった。たぶんJavaのソースに実装がありそう?
ここにはunary_~とかunary_-とかが書いてあったので、これが前置演算子になるんだなーと分かった。https://github.com/scala/scala/blob/2.11.x/src/library/scala/Int.scala#L39..L43
さらにgit grep 'def to('とかして探してみると、src/library/scala/runtime/RichInt.scalaというファイルが見つかった。ここにtoの定義を発見。https://github.com/scala/scala/blob/2.11.x/src/library/scala/runtime/RichInt.scala#L71..L71 。Range.Inclusiveというのが返るみたい。どうやってRichIntとかが呼ばれるのかよくわからないのだけど、聞いてみるとimplicit conversionみたいな仕組みが使われるみたい。よくわからんけど、もっと読んでったら分かりそう。
会話もした。
toの実装探してて、RichIntっていうの見つけたけど、どう使われるんだろう
— 柴崎優季 (@shiba_yu36) 2015年3月21日
@shiba_yu36 1.to(5) とかすると Int に to メソッドないのでInt から変換(implicit conversion) できる型(で toメソッドがあるもの) を探しに行って RichInt がみつかって使われる感じだったと思います。
— 目茶色い (@mechairoi) 2015年3月21日
@mechairoi なるほど!ちなみにInt自体の実装ってどの辺にあるんでしょうか。src/library/scala/Int.scalaはあったけど、これはabstract classっぽかった。なんかJavaと繋がる感じですか
— 柴崎優季 (@shiba_yu36) 2015年3月21日
@shiba_yu36 たぶん Java の Int と同じものっぽい?
— 目茶色い (@mechairoi) 2015年3月21日
@mechairoi じゃあhttp://t.co/4ChhvvNdehだけみても分からなくて、Java見ろって感じですね
— 柴崎優季 (@shiba_yu36) 2015年3月21日
@shiba_yu36 インタフェースだけだったら http://t.co/lsOA9uoL4X でわかりそうだけど実装みようとするとJava見ることになりそう
— 目茶色い (@mechairoi) 2015年3月21日
@mechairoi なるほど〜
— 柴崎優季 (@shiba_yu36) 2015年3月21日