How does pattern matching work in Akka.Actor method?

I am new to Scala programming and do not understand how actors work and how to use them correctly.

Looking at the source code of Akka Akka , the following is shown:

trait Actor {
  def receive: Actor.Receive // Actor.Receive = PartialFunction[Any, Unit]
}

      

My first impression of this is that an Actor is a trait that provides one abstract method receive

, that takes no arguments, and then returns a partial function. The first question is, is this the correct interpretation of the API?

Then I went through the documentation on how to implement members. Examples look something like this:

class HelloActor extends Actor {
  def receive = {
    case "hello" => println("hello back at you")
    case _       => println("huh?")
  }
}

      

Clearly there is some pattern matching going on here, but I am having a hard time understanding how it works. For example, let's say I wanted to call the receive method directly, without using something like send

, how would I do it?

+3


source to share


2 answers


as others have already answered, you should never directly call methods on Actors. But your question seems to be more about "how does PartialFunction work in Scala?", Right?

Scala PartialFunction[In, Out]

has a bit of compiler-generated code for methods such as isDefinedAt

, so you can define a partial function if it is defined for a specific argument:

scala> val fun: PartialFunction[Any, String] = {
     | case 42 => "yes"
     | }
fun: PartialFunction[Any,String] = <function1> 

scala> fun.isDefinedAt(12)
res0: Boolean = false

scala> fun.isDefinedAt(42)
res1: Boolean = true

scala> fun(42)
res2: String = yes

scala> fun(12)
scala.MatchError: 12 (of class java.lang.Integer)

      



``,

We use a method isDefinedAt

before we apply the message to the function receive

, and if it fails to process the message, we pass it to unhandled(msg)

, which usually just writes the message in dead letters so you can understand that your Actor hasn't processed the message.

+3


source


For example, let's say that I wanted to call the receive method directly without using something like send, how would I do that?

You wouldn't do that.

Calling an receive

actor function directly without going through it ActorRef

violates the guarantees of the actor model:



  • Actors process exactly one message at a time.
  • The internal state of an actor can only be mutated from the receive function.

(among others, see What is an actor? )

When you send a message ActorRef

, you are not directly talking to the actor. Hidden behind ActorRef

is any number of implementation details - you can send a message to a router or a remote player or a dead actor (or all three!). Isolating the details of the actor behind this link ensures that these are all points in the actor's model.

+2


source







All Articles