1

我正在与 akka 演员合作。所有参与者都应实现该receive方法,该方法的签名为PartialFunction[Any, Unit]. 我想定义一个更严格的函数来匹配签名,比如PartialFunction[Action, Unit]. 但是,这不会编译:

class PlayerActor extends Actor with {
  override def receive: Receive = rec

  def rec: PartialFunction[Action, Unit] = {
    case Jump() =>
  }
}

我想这样做,所以如果我忘记了一个案例,编译器会警告我。

Receive定义为type Receive = PartialFunction[Any, Unit]


我最终像手动一样:

override def receive = {
  case a: Action => rec(a)
}

也可以通过强制转换来完成:

override def receive = rec.asInstanceOf[PartialFunction[Any, Unit]]

或通过隐式转换:

implicit def toAnyPartial[T](f: PartialFunction[T, Unit]): PartialFunction[Any, Unit] =
  f.asInstanceOf[PartialFunction[Any, Unit]]
4

3 回答 3

2

你可以试试这个

def rec: Receive  = { case a: Action => a match {
  case Jump() =>
}}
于 2012-12-14T16:59:02.693 回答
1

PartialFunction在其第一个类型参数上是逆变的。我不会深入解释这意味着什么(有书籍、博客文章、SO 问题和答案),而是会给你一个非常琐碎的例子。

您可以Any通过receive. 如果可以分配recreceive,则意味着您可以传递Anyrec,从而绕过rec的类型。编译器禁止它。

于 2012-12-14T16:01:35.803 回答
1

如果您只想PartialFunction[Any, Unit]使用类型的实现来创建,PartialFunction[T, Unit]您可以试试这个:

implicit def toPfAny[T](pf: PartialFunction[T, Unit]): PartialFunction[Any, Unit] = {
  object PF { def unapply(a: T): Option[Unit] = pf.lift(a) }
  { case PF(_) => () }
}

用法:

scala> def impl: PartialFunction[String, Unit] = { case s => println(s) }
impl: PartialFunction[String,Unit]

scala> def receive: PartialFunction[Any, Unit] = impl
receive: PartialFunction[Any,Unit]
于 2012-12-14T16:33:35.730 回答