1

这是一个最小的例子

package org.example

import akka.actor._
import akka.pattern.ask
import akka.util.duration._
import akka.util.Timeout

class Counter extends Actor {
  def receive = {
    case _  => sender ! "hi"
  }
}

object AkkaProjectInScala extends App {
  val system = ActorSystem("AkkaProjectInScala")

  val counter = system.actorOf(Props[Counter])

  // this will raise NullPointerException    
  (counter ? "i just came to say hello") onSuccess {
    case x => println("He said " + x)
  }

  implicit val timeout = Timeout(5 seconds)
  system.shutdown()
}

这看起来很奇怪,因为当我在控制台中尝试这样的事情时,隐式会引发编译错误

scala> def magic(a: Int)(implicit b: Int) = a + b
magic: (a: Int)(implicit b: Int)Int

scala> magic(3)
<console>:9: error: could not find implicit value for parameter b: Int
              magic(3)

使用 Akka 时是否会发生其他一些魔术,从而阻止编译器在编译时检测到这一点?

4

2 回答 2

1

发送消息时超时尚未初始化。所有val都按照它们在源代码中出现的顺序进行初始化。不属于方法主体的代码是构造函数代码,包括“独立”代码,例如您的消息发送代码和timeout. 所以隐式在初始化之前就被引用了。

于 2013-03-15T13:45:37.367 回答
1

您没有说明您使用的版本,但我猜它不是 Akka 2.1,因为持续时间已移至scala.concurrent. 但是,使用 Scala 2.10.1-RC3 和 Akka 2.1 时,当我尝试编译您的代码时,它会抱怨缺少 ExecutionContext (可以使用 导入import scala.concurrent.ExecutionContext.Implicits.global)。此外,它没有在 ask-pattern 之后定义的超时编译。解决编译问题后,它对我来说很好。所以,我建议你使用最新版本。

这里又是工作代码 - 使用 Akka 2.1

import scala.concurrent.duration._

import akka.actor._
import akka.dispatch._
import akka.util.Timeout
import akka.pattern.ask
import scala.concurrent.ExecutionContext.Implicits.global


class Counter extends Actor {
  def receive = {
    case _  => sender ! "hi"
  }
}

object AkkaProjectInScala extends App {
  val system = ActorSystem("AkkaProjectInScala")

  val counter = system.actorOf(Props[Counter])
  implicit val timeout = Timeout(5 seconds)

  val future = (counter ? "i just came to say hello") 
  future onSuccess {
    case x => println("He said " + x)
  }

  system.shutdown()
}
于 2013-03-15T18:00:29.770 回答