for (i : Int <- 1 to 5) { ... }
以前、for文の記事 を書いたとき、なぜ、わざわざ java の for ( int i=0; i<10; i++) と異なる構文を用意したかと思っていたが、 実はこういうことだった。
val range : Range = 1 to 5. for (i : Int <- range ) { ... }
Range 型オブジェクトに対する 拡張 for 文だった。
(「拡張」 for 文というか、結局 Scala の for 文はこの形式だけ)
Scala では「1」や「2」などの primitive もオブジェクト扱いなのでメソッドが呼び出せる。
値を返すメソッドは中置記法で書けるので一見気が付きにくい。
for (i : int <- 1 to 5) { ... } も
for (i : int <- 1.to(5)) { ... }
と書けば Int 型のメソッドが実行されて何かができていることが一目でわかる。
どうも Scala の中にはこういう罠があちこちにあるような気がする・・・
Intクラスのドキュメンテーションによれば、
* There is an implicit conversion from [[scala.Int]] => [[scala.runtime.RichInt]] * which provides useful non-primitive operations.
とうことなので実際に to 等のメソッドが用意されているのは RichInt クラスになる。
RichInt クラスで定義されている Range 型を返すメソッドを見てみると、
def until(end: Int): Range = Range(self, end) def until(end: Int, step: Int): Range = Range(self, end, step) def to(end: Int): Range.Inclusive = Range.inclusive(self, end) def to(end: Int, step: Int): Range.Inclusive = Range.inclusive(self, end, step)
がある。
ステップ指定付きの to() を使ってみよう。
for (i : Int <- 1 to (10,2)) print(i);
13579
until() が Range 型を返しているのに対して、 to() は Range.Inclusive を返している。
Range 型では終端値は含まないのに対して、その派生型である Range.Inclusive は終端値を含むという違いがある。
for (i : Int <- 1 to 5) print(i); println; for (i : Int <- 1 until 5) print(i);
12345 1234
0 件のコメント:
コメントを投稿