Raphael Roth Raphael Roth - 10 days ago 5
Scala Question

Pattern matching in a scala method without arguments

I recently looked into scala multithreading tutorials and stumbled on a method which is implemented in an Actor:

class MyActor extends Actor
def receive = {
case "test" => println("received test")
case _ => println("received unknown message")
}
}


Although I think I know what the method does, I can't figure out how to use such a method (at it does not take any arguments).

Althouh the example is about Akka, I think this is unrelated to Akka

Answer

Actually receive returns partial function. When you check the source code of Actor you'll see that;

type Receive = PartialFunction[Any, Unit]

So it means with overriding receive you're providing a partial function which takes any parameter and return unit. At some point later, if your actor gets a message Akka itself will use this partial function to do pattern match over the incoming message.

-- Edit --

For more concrete example, let say you created a similar object;

object Obj {
  def receive: PartialFunction[Any, Unit] = {
    case "test" => println("test case")
    case 1 => println("int 1 case")
    case d: Double => println("double case $d")
    case _ => println("rest")
  }
}

Then you can call this partial function like regular method call;

scala> Obj.receive(1)
int 1 case
scala> Obj.receive("test")
test case

Actor case is specific, it's just that you don't call the receive directly, you provide it and Akka itself calls it if the messages arrive;

protected[akka] def aroundReceive(receive: Actor.Receive, msg: Any): Unit = receive.applyOrElse(msg, unhandled)

Of course this call depends on lots of parameters like the topology you use,mailbox and etc.

Comments