LoginSignup
2
2

More than 5 years have passed since last update.

for式はforeach

Posted at

for式はforeach

社内の勉強会で

for式はforeachに展開される。
なので、自前のクラスでもforeachを実装すれば、for式で回せる。

っていう話をしたので、実証してみる。


まずは「for式がforeachに展開される」ことを確認。

package sample1

object Main extends App {

  val seq = Seq(1, 2, 3)

  for (i <- seq) println(i)

}

コンパイル時に-Xprint:typerつけてホントかどうか見てみる。

$ scalac -Xprint:typer sample1.scala

↓こんなの出ました。

[[syntax trees at end of                     typer]] // sample1.scala
package sample1 {
  object Main extends AnyRef with App {
    def <init>(): sample1.Main.type = {
      Main.super.<init>();
      ()
    };
    private[this] val seq: Seq[Int] = collection.this.Seq.apply[Int](1, 2, 3);
    <stable> <accessor> def seq: Seq[Int] = Main.this.seq;
    Main.this.seq.foreach[Unit](((i: Int) => scala.this.Predef.println(i)))
  }
}

foreachになってますね。


次に、自前のクラスをfor式で回してみる。
foreachのシグニチャはこんなの。

def foreach(f: (A)  Unit): Unit

これを実装すればOKのはず。

package sample2

object Main extends App {

  object Eachable {
    import scala.util.Random

    private val random = new Random

    // ランダムな数値をエサに3回「f」を呼び出す。
    def foreach(f: (Int) => Unit) = {
      f(random.nextInt)
      f(random.nextInt)
      f(random.nextInt)
    }
  }

  for (i <- Eachable) println(i)

}

レッツ、コンパイル。

[[syntax trees at end of                     typer]] // sample2.scala
package sample2 {
  object Main extends AnyRef with App {
    def <init>(): sample2.Main.type = {
      Main.super.<init>();
      ()
    };
    object Eachable extends scala.AnyRef {
      def <init>(): sample2.Main.Eachable.type = {
        Eachable.super.<init>();
        ()
      };
      import scala.util.Random;
      private[this] val random: scala.util.Random = new scala.util.Random();
      <stable> <accessor> private def random: scala.util.Random = Eachable.this.random;
      def foreach(f: Int => Unit): Unit = {
        f.apply(Eachable.this.random.nextInt());
        f.apply(Eachable.this.random.nextInt());
        f.apply(Eachable.this.random.nextInt())
      }
    };
    Main.this.Eachable.foreach(((i: Int) => scala.this.Predef.println(i)))
  }
}

foreachになってますね。
動かしてみると、3回テキトーな数字が表示されます。


gistにコード全文。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2