PartialFunction与Function1的语法方式

Meh*_*ran 3 scala akka

在学习Scala和Akka的过程中,我试图了解人们如何发现一个PartialFunction

在“编程反应系统”课程中,有一个Actor的示例:

class Toggle extends Actor {
  def happy: Receive = {
    case "How are you?" =>
      sender ! "happy"
      context become sad
  }
  def sad: Receive = {
    case "How are you?" =>
      sender ! "sad"
      context become happy
  }
  def receive = happy
}
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的过程,我会说我理解它正在尝试做的事情。我不明白的事情是,happysad有型的Function1(或至少这是我的信念),但他们能发挥的作用的PartialFunctionreceive需要PartialFunction)。

而且甚至更糟糕的是,根据Akka文档receive应该返回一个PartialFunction(不是一个):

抽象def接收:Actor.Receive

Scala API:这定义了初始actor行为,它必须返回具有actor逻辑的部分函数。

但是据我所知,happy并且sad不返回a PartialFunction,它们是一个。

总结我的问题:

  1. 有没有办法发现PartialFunction反对Function1
  2. 我读的例子错了吗?是不是receive一个PartialFunction是回报Unit?如果答案是肯定的,那么为什么文档说receive应该返回PartialFunction??

[更新]

根据我从@Brian McCutchon得到的答案,现在我知道该receive方法应该返回PartialFunction。但这根本无法解决我的困惑!请考虑以下情形:

def someFunction(): Receive = {
  //Instantiates and returns a Receive object
}

class Toggle {
  def happy: Receive = {
    case "How are you?" =>
      someFunction()
  }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,Scala编译器如何知道给定的代码是否应该扩展为:

class Toggle {
  def happy: Receive = {
    return {
      case "How are you?" =>
        someFunction() // <-- The returned object of this function call is dismissed
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

或这个:

class Toggle {
  def happy: Receive = { // <-- Starting point of happy's body
    case "How are you?" =>
      someFunction() // <-- The Receive object is returned by this method
  }
}
Run Code Online (Sandbox Code Playgroud)

更重要的是,我应该如何知道将发生哪种扩展?而且我认为现代编程语言应该更具可读性!!!

Bri*_*hon 7

happy并且sad属于Function1类型

不,它们是return的方法Receive,这是的类型别名PartialFunction[Any, Unit]。您提供的类型注释显示了此返回类型。部分函数可以使用与Function1(和其他SAM类型)相同的lambda语法,在这种情况下,它们只能通过上下文(在这种情况下,您的类型注释)来区分。

receive应该返回一个PartialFunction(不是一个)

您对术语感到困惑。receive是方法,而不是PartialFunction您用声明的方法def。它返回一个PartialFunction[Any, Unit](aka Receive)。这也应该澄清您对happy和的困惑sad

这是混乱的合理来源,因为语法是如此简洁,以使它看起来像receivePartialFunction它的回报是一回事。这可能有助于认识到您的代码可以扩展为此(尽管我在实践中不建议这样做):

class Toggle extends Actor {
  def happy: Receive = {
    return {
      case "How are you?" =>
        sender ! "happy"
        context become sad
    }
  }
  def sad: Receive = {
    return {
      case "How are you?" =>
        sender ! "sad"
        context become happy
    }
  }
  def receive = {
    return happy
  }
}
Run Code Online (Sandbox Code Playgroud)

根据您的更新,第一个扩展是正确的。第二个没有意义,因为方法主体不能以开头case,这应该提示您正在处理lambda。总结一下:如果一个块以lambda参数开头(例如x =>),或者它以case而不是match块开头,则为lambda。