scala - PartialFunction 与 Function1 语法方面

标签 scala akka

作为我学习 Scala 和 Akka 之旅的一部分,我试图了解如何发现 PartialFunction

在“Programming Reactive Systems”类(class)中,有一个 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
}

这是一个非常简单的问题,我会说我理解它要做什么。我不明白的是 happysad 属于 Function1 类型(或者至少这是我的信念),但它们可以扮演 PartialFunction 的角色(receive 需要一个 PartialFunction)。

甚至比这更糟,基于 Akka documentationreceive 应该返回一个 PartialFunction(不是一个):

abstract def receive: Actor.Receive

Scala API: This defines the initial actor behavior, it must return a partial function with the actor logic.

但据我所知,happysad 没有返回 PartialFunction,它们是一个。

总结我的问题:

  1. 有没有办法根据 Function1 发现 PartialFunction
  2. 我是不是看错了这个例子? receive 不是返回 UnitPartialFunction 吗?如果答案是肯定的,那么为什么文档说 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()
  }
}

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

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

或者这个:

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

或者更重要的是,我怎么知道会发生哪种扩张?而且我认为现代编程语言应该更具可读性!!!

最佳答案

happy and sad are of type Function1

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

receive is supposed to return a PartialFunction (not being one)

您对术语感到困惑。 receive 是一种方法,而不是 PartialFunction,正如您使用 def 声明的那样。它返回一个 PartialFunction[Any, Unit](又名 Receive)。这也应该澄清您对 happysad 的困惑。

这是一个合理的混淆来源,因为语法如此简洁以至于看起来像 receive 和它返回的 PartialFunction 是一回事。意识到您的代码可以扩展到此可能会有所帮助(尽管我在实践中不建议这样做):

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

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

关于scala - PartialFunction 与 Function1 语法方面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55203709/

相关文章:

scala - 为什么 PersistentActor 的方法 persist 不返回 Future?

scala - Akka-http:如何在单元测试中模拟 ActorMaterializer

scala - 在Scala中扩展部分实现的局部函数

scala - YARN 因超出内存限制而杀死容器

scala - Spark : Writing data frame to s3 bucket

java - Scala 可迭代和 Java 可迭代

akka - 如何检测 Akka actors?

scala - 如何为 Gatling 场景设置 cookie

scala - Scala 的 Option 以何种方式折叠 catamorphism?

scala - 如何处理发出 Future[T] 的源?