2012年6月26日火曜日

[Scala] 拡張for文

Scalaの拡張For文はこんな感じだった。

val a : Array[String] = Array("x", "y", "z");
for (s: String <- a) print(s);

この構文は scala.collection.IterableLike インターフェース(Scale的にはtraitと呼ぶ)の
foreach[U](f: A => U): Unit
を呼び出すことで実現されている。

実際には、IterableLike traitを実装しなくても、
単に、foreach[U](f: A => U): Unitが実装されていれば拡張for文を使用できる。

手抜きだけれどもこんな感じになる。

object ForSample {
  def main(args: Array[String]) {
    val fe : ForEachable = new ForEachable();
    for (i: Int <- fe) print(i);
  }
}
class ForEachable {
  def foreach[U](f: Int => U): Unit = {
    f(1);
    f(2);
  }
}
実行すると
12

胡散臭すぎる。
for文ぽく書いてはあるが、結局対象オブジェクトのforeachを呼び出すための構文のようだ。

留意するべきは、一見、対象のオブジェクトから値を取り出してfor文本体を実行しているように見えるが、実際にはfor文本体の実行部をどのように使うかもすべて対象のオブジェクト側にゆだねられている。
全く使ってくれないかもしれないし、2回づつ呼ばれるかもしれない。

object ForSample {
  def main(args: Array[String]) {
    val fe : ForEachable = new ForEachable();
    for (i: Int <- fe) print(i);
  }
}
class ForEachable {
  def foreach[U](f: Int => U): Unit = {
    f(1); f(1);
    f(2); f(2);
  }
}
実行結果:
1122

Javaチックな構文に騙されてはいけない。

0 件のコメント:

コメントを投稿