作为我学习 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
}
这是一个非常简单的问题,我会说我理解它要做什么。我不明白的是 happy
和 sad
属于 Function1
类型(或者至少这是我的信念),但它们可以扮演 PartialFunction
的角色(receive
需要一个 PartialFunction)。
甚至比这更糟,基于 Akka documentation ,receive
应该返回一个 PartialFunction
(不是一个):
abstract def receive: Actor.Receive
Scala API: This defines the initial actor behavior, it must return a partial function with the actor logic.
但据我所知,happy
和 sad
没有返回 PartialFunction
,它们是一个。
总结我的问题:
- 有没有办法根据
Function1
发现PartialFunction
? - 我是不是看错了这个例子?
receive
不是返回Unit
的PartialFunction
吗?如果答案是肯定的,那么为什么文档说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
andsad
are of type Function1
不,它们是返回 Receive
的方法,它是 PartialFunction[Any, Unit]
的类型别名。您提供的类型注释显示了此返回类型。部分函数可以使用与 Function1
(和其他 SAM types)相同的 lambda 语法,在这种情况下,它们仅通过上下文(在本例中为您的类型注释)进行区分。
receive
is supposed to return aPartialFunction
(not being one)
您对术语感到困惑。 receive
是一种方法,而不是 PartialFunction
,正如您使用 def
声明的那样。它返回一个 PartialFunction[Any, Unit]
(又名 Receive
)。这也应该澄清您对 happy
和 sad
的困惑。
这是一个合理的混淆来源,因为语法如此简洁以至于看起来像 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/