4

我创建了Value Class

final class Feature(val value: Vector[Double]) extends AnyVal

反对match该类:scala

val d = new Feature(Vector(1.1))
s match {
  case a:Feature => println(s"a:feature, $a")
  case _ => println("_")
}

这可以正常工作,但是在Akka与上面相同的类中,在receive方法中这不起作用:

  def receive = LoggingReceive {
    case a:Feature =>
      log.info("Got Feature: {}", a)
    case _ => println("_")
  }

当我执行代码时,虽然我正在发送一个Featurecase正在执行的语句是case _ => println("_"),但是,如果我将代码更改为:

  def receive = LoggingReceive {
    case a:Feature =>
      log.info("Got Feature: {}", a)
    case b:Vector[_] =>
      log.info("GOT FEATURE")
    case _ => println("_")
  }

case b:Vector[_]被执行。

Akka 文档提到:

实例化actor props 的推荐方法在运行时使用反射来确定要调用的正确actor构造函数,并且由于技术限制,当所述构造函数采用值类的参数时,不支持该构造函数。在这些情况下,您应该解压缩参数或通过手动调用构造函数来创建道具:

但不要提及匹配Value classes

更新

感谢 YuvalItzchakov 的帮助。Actor的代码如下:

收到消息的演员:

  def receive = LoggingReceive {
    case Feature(a) =>
      log.info("Got feature {}", a)
    // ....
  }

发送消息的演员:

  def receive = LoggingReceive {
    // ..
    case json: JValue =>
      log.info("Getting json response, computing features...")
      val features = Feature(FeatureExtractor.getFeatures(json))
      log.debug(s"Features: $features")
      featureListener.get ! features
    // ..
  }
4

1 回答 1

2

由于值类如何工作的性质,您的两个示例都将导致Feature. 一次是由于您的模式匹配示例中的运行时检查,另一次是由于其签名receive需要Any作为输入类型。

正如值类的文档所指定的(强调我的):

分配摘要

值类实际上在以下情况下被实例化:

  • 值类被视为另一种类型
  • 一个值类被分配给一个数组。
  • 进行运行时类型测试,例如模式匹配

这意味着如果您看到一个Vector[_]类型,这意味着您实际上是从代码中的某个位置传递了一个具体的向量。

于 2017-02-17T12:24:41.150 回答