Actor使い始め

まず文字列によるメッセージ送信。

import scala.actors.Actor
import scala.actors.Actor._

class X extends Actor {
    def act() = {
        react {
            case "test" => println("received test")
            case _      => println("received unknown message")
        }
    }
}

object Main extends Application {
    val x = new X()
    x.start

    x ! "test"
}
received test

case objectを使ったメッセージ送信。(引数なしと引数あり)

import scala.actors.Actor
import scala.actors.Actor._

case object NoArg
case class OneArg(n: Int)
case object Stop

class X extends Actor {
    def act() = loop {
        react {
            case NoArg     => println("received NoArg")
            case OneArg(n) => println("received OneArg : " + n)
            case Stop      => exit()
            case _         => println("received unknown message")
        }
    }
}

object Main extends Application {
    val x = new X()
    x.start

    x ! NoArg
    x ! OneArg(3)
    x ! Stop
}
received NoArg
received OneArg : 3

複数回メッセージを受信する場合にはloopを書かないといけないようです。


replyを使用すると、送信元に返信を送れる。
送信側は!の代わりに!?でメッセージを送信する。
(replyは、Erlangにはない特徴だそうです。)

import scala.actors.Actor
import scala.actors.Actor._

class X extends Actor {
    def act() = {
        receive {
            case "request" => reply("response")
            case _         => println("received unknown message")
        }
    }
}

object Main extends Application {
    val x = new X()
    x.start

    val result = x !? "request"
    println(result)
}
response


!?の結果をStringで受けようとしたらコンパイルエラーになった。
Anyが返される模様。
特定の型で受けたい場合はパターンマッチすればいいようです。

import scala.actors.Actor
import scala.actors.Actor._

class X extends Actor {
    def act() = {
        receive {
            case "request" => reply("response")
            case _         => println("received unknown message")
        }
    }
}

object Main extends Application {
    val x = new X()
    x.start

    x !? "request" match {
        case result: String => println(result)
    }
}
response