在 Akka 中匹配值 类
Matching against Value Classes in Akka
我创建了 Value Class
final class Feature(val value: Vector[Double]) extends AnyVal
match
反对scala
中的class:
val d = new Feature(Vector(1.1))
s match {
case a:Feature => println(s"a:feature, $a")
case _ => println("_")
}
这工作正常,但在 Akka
中,与上面相同的 class,在 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 文档提到:
The recommended way to instantiate actor props uses reflection at runtime to determine the correct actor construc-
tor to be invoked and due to technical limitations is not supported when said constructor takes arguments that are
value classes. In these cases you should either unpack the arguments or create the props by calling the constructor
manually:
但不要提及匹配 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
// ..
}
由于值 类 工作方式的性质,您的两个示例都会导致 Feature
的分配。一次是由于 run-time 检查您的模式匹配示例,另一个是由于 receive
的签名需要 Any
作为输入类型。
正如 docs for Value Classes 指定的(强调我的):
Allocation Summary
A value class is actually instantiated when:
- a value class is treated as another type.
- a value class is assigned to an array.
- doing runtime type tests, such as pattern matching.
这意味着如果您看到 Vector[_]
类型,则意味着您实际上从代码中的某个位置传递了一个具体向量。
我创建了 Value Class
final class Feature(val value: Vector[Double]) extends AnyVal
match
反对scala
中的class:
val d = new Feature(Vector(1.1))
s match {
case a:Feature => println(s"a:feature, $a")
case _ => println("_")
}
这工作正常,但在 Akka
中,与上面相同的 class,在 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 文档提到:
The recommended way to instantiate actor props uses reflection at runtime to determine the correct actor construc- tor to be invoked and due to technical limitations is not supported when said constructor takes arguments that are value classes. In these cases you should either unpack the arguments or create the props by calling the constructor manually:
但不要提及匹配 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
// ..
}
由于值 类 工作方式的性质,您的两个示例都会导致 Feature
的分配。一次是由于 run-time 检查您的模式匹配示例,另一个是由于 receive
的签名需要 Any
作为输入类型。
正如 docs for Value Classes 指定的(强调我的):
Allocation Summary
A value class is actually instantiated when:
- a value class is treated as another type.
- a value class is assigned to an array.
- doing runtime type tests, such as pattern matching.
这意味着如果您看到 Vector[_]
类型,则意味着您实际上从代码中的某个位置传递了一个具体向量。