为什么我得到NullPointerException与Akka缺少隐式而不是编译错误?

时间:2013-03-15 12:22:22

标签: scala compilation akka

这是一个最小的例子

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()
}

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

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时是否会发生其他一些魔法,这会阻止编译器在编译时检测到它?

2 个答案:

答案 0 :(得分:1)

发送邮件时,尚未初始化超时。所有val都按照它们在源代码中出现的顺序进行初始化。不属于方法体的代码是构造函数代码,包括“自由站立”代码,如消息发送代码和timeout的初始化。因此隐式在初始化之前被引用。

答案 1 :(得分: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()
}