Scala演员中的'self'是如何工作的?

3
以下代码片段摘自《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
   }
 }
}

首先,在 react {} 中,对 act() 的递归调用有什么作用?看起来所有的情况都会失败,它只是简单地跳过到最后什么也不做。

其次,在这本书中,他们使用了以下 REPL 示例:

NameResolver ! ("www.scala-lang.org", self)

'self'是从哪里来的?我尝试在主方法中复制这个。

 def main(args: Array[String]) {
   NameResolver.start()
   NameResolver ! ("www.scala-lang.org", Actor.self)
 }

上述方法不起作用。


1
你能详细说明一下“上述方法不起作用”的原因吗? - Didier Dupont
2个回答

3
  1. act() 会递归运行,除非你发送了一个 EXIT 消息。对于任何其他既不匹配 EXIT 也不匹配 (name: String, actor: Actor) 的消息,将使用 case msg。换句话说,case msg 是一种通用处理程序,用于处理所有未匹配的消息。

  2. Actor.self 是一个可靠的方式在actor内部引用actor实例(建议使用 self 而不是 this,以引用正确的实例)。在您的情况下,您正在从一个非actor中调用 Actor.self,因此它失败了。


2
  1. react 中的代码仅在 新的 消息到来时调用。因此,如果你在 case 子句中递归调用 act(),则该 Actor 将“等待”直到收到新消息(而不会阻塞线程)。这是当您想根据接收到的内容更改 Actor 行为时,替代使用 loop 的一种方法。当您收到 "EXIT" 时,将停止等待消息。

  2. self 应该在每次 Actor 内部使用 this 时使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接