The following code snippet is taken from Programming in Scala
import actors.Actor
object NameResolver extends Actor {
import java.net.{InetAddress, UnknownHostException}
def act() {
react {
case (name: String, actor: Actor) =>
actor ! getIp(name)
act()
case "EXIT" =>
println("Name resolver exiting.")
// quit
case msg =>
println("Unhandled message: " + msg)
act()
}
}
def getIp(name: String): Option[InetAddress] = {
try {
Some(InetAddress.getByName(name))
} catch {
case _: UnknownHostException => None
}
}
}
Firstly within react {} what does the recursive call to act() do? It looks like all the cases would fail and it will simply drop through to the end doing nothing.
Secondly in the book, they use the following REPL example
Na开发者_StackOverflowmeResolver ! ("www.scala-lang.org", self)
Where does 'self' come from? I have tried to replicate this in a main method
def main(args: Array[String]) {
NameResolver.start()
NameResolver ! ("www.scala-lang.org", Actor.self)
}
The above does not work
act()
runs recursively, unless you send anEXIT
message. For any other message that neither matchEXIT
nor(name: String, actor: Actor)
,case msg
will be used. In other wordscase msg
is a kind of a generic handler that processes all the unmatched messages.Actor.self
is a reliable way to refer to the actor instance from within an actor's body (it's recommended to useself
instead ofthis
, to refer to the right instance). In your case, you're callingActor.self
not from an actor, and, thus, it fails.
The code inside
react
is called only when a new message is available. Thus, if you call recursivelyact()
inside acase
clause, the actor will "wait" until a new message is sent (without blocking a thread). It's an alternative toloop
when you want to change the behavior of the actor according to what it received. Here you stop waiting for messages when you get"EXIT"
.self
is supposed to be used inside an actor everytime you want to usethis
.
精彩评论