我已经创建了Value Class
final class Feature(val value: Vector[Double]) extends AnyVal
在scala
中针对该类别的match
:
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("_")
}
当我执行代码时,尽管我发送了一个Feature
,但正在执行的case
语句是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文档提到:
实例化行动者道具的推荐方法在运行时使用反射来确定正确的参与者构造 要调用的tor,并且由于所述构造函数采取的论点是 价值类。在这些情况下,您应该解开参数或通过调用构造函数来创建道具 手动:
,但没有提及与Value classes
更新
感谢Yuvalitzchakov的帮助。演员的代码如下:
接收消息的演员:
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
// ..
}
由于价值类的工作方式,您的两个示例都会导致Feature
的分配。一旦在您的模式匹配示例中进行运行时间检查,而另一个由于receive
的签名,该签名需要Any
作为输入类型。
作为价值类指定的文档(强调我的):
分配摘要
实际上是在以下情况下实例化的。
- 值类被视为另一种类型。
- 一个值类被分配给数组。
- 做运行时类型测试,例如模式匹配。
这意味着,如果您看到Vector[_]
类型,则意味着您实际上从代码中的某个位置传递了混凝土向量。