【问题标题】:Scala case syntax understandingScala案例语法理解
【发布时间】:2014-02-08 13:02:48
【问题描述】:

我正在尝试了解 Scala 的演员 (Akka),但我只是遇到了一些我不明白的奇怪的“案例”用法:

import akka.actor.{ ActorRef, ActorSystem, Props, Actor, Inbox }
import scala.concurrent.duration._

case object Greet
case class WhoToGreet(who: String)
case class Greeting(message: String)

class Greeter extends Actor {

    var greeting = ""

    def receive = {
        case WhoToGreet(who) => greeting = s"hello, $who"
        case Greet           => sender ! Greeting(greeting) // Send the current greeting back to the sender
    }

}

特别是这一点:

  def receive = {
      case WhoToGreet(who) => greeting = s"hello, $who"
      case Greet           => sender ! Greeting(greeting) // Send the current greeting back to the sender
  }

现在我认为 scala 中的 case 语法如下所示:

something match {
    case "val1" => println("value 1")
    case "val2" => println("value 2")
}

如果我尝试像这样在 scala REPL 中复制有问题的用法:

def something = {
    case "val1" => println("value 1")
    case "val2" => println("value 2")
}

我明白了

error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)

这到底是什么意思?

更新:这篇文章是我问题的最佳答案:http://blog.bruchez.name/2011/10/scala-partial-functions-without-phd.html

【问题讨论】:

    标签: scala akka


    【解决方案1】:

    scala 中的大小写语法有多种形式。

    一些例子是:

    case personToGreet: WhoToGreet => println(personToGreet.who)
    case WhoToGreet(who) => println(who)
    case WhoToGreet => println("Got to greet someone, not sure who")
    case "Bob" => println("Got bob")
    case _ => println("Missed all the other cases, catchall hit")
    

    您看到该错误的原因是您没有尝试对已知对象调用 ma​​tch,而是尝试将 case 块分配给函数。

    因为 Case 块实际上只是一个 PartialFunction,编译器认为您正在尝试定义一个部分函数,​​但没有提供足够的信息,因为它没有可应用的内容。

    尝试类似:

    def something: PartialFunction[Any,Unit] = {
        case "val1" => println('value 1")
        case _ => println("other")
    }
    

    您将能够调用它。

    编辑

    Akka 示例中的案例之所以有效,是因为您实际上是在为一个抽象的、预先存在的函数提供一个实现:receive 是在 akka.actor.Actor 中定义的。你可以在Akka source看到typedef:

    object Actor {
      type Receive = PartialFunction[Any, Unit]
      ..
    }
    
    trait Actor {
      def receive: Actor.Receive 
      ....
    } 
    

    示例中的receive调用被编译为

    def receive: PartialFunction[Any, Unit] = {
    }
    

    这告诉我们 Receive 将接受任何值或引用并返回一个单位。

    【讨论】:

    • 嗯,我知道match 可以工作,但我的问题仍然存在——为什么它适用于没有match 的Akka 示例?我在网上找不到对此类语法的任何引用。
    • 对不起,我完全错过了你正在寻找的澄清。在答案中编辑:)
    • @Caballero 它与receive 一起工作的原因是因为您要覆盖它,而父类型Actor 定义了函数的类型,即PartialFunction...。要定义自己的部分函数,​​您需要做的就是定义正确的返回类型(PartialFunction)。有关示例,请参阅文档:scala-lang.org/api/2.10.3/index.html#scala.PartialFunction
    猜你喜欢
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多