简体   繁体   English

匹配Akka中的值类

[英]Matching against Value Classes in Akka

I've created the Value Class 我创造了Value Class

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

To match against that class in scala : 要在scala match该类:

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

This works correctly, but in Akka , with the same class above, in the receive method this is not working: 这是正常的,但在Akka ,与上面相同的类,在receive方法中,这是行不通的:

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

When I execute the code, although I am sending a Feature , the case statement that is being executed is case _ => println("_") , but, If I change the code to this: 当我执行代码时,虽然我正在发送一个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[_] is executed. case b:Vector[_]执行case b:Vector[_]

Akka documentation mentions: 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. 实例化actor道具的推荐方法是在运行时使用反射来确定要调用的正确的actor构造函数,并且当所述构造函数接受值为类的参数时,不支持由于技术限制。 In these cases you should either unpack the arguments or create the props by calling the constructor manually: 在这些情况下,您应该通过手动调用构造函数来解压缩参数或创建props:

But do not mention nothing about matching against Value classes 但是不要提及与Value classes匹配的任何内容

Update 更新

Thanks to YuvalItzchakov for the help. 感谢YuvalItzchakov的帮助。 The Actor's code is as below: 演员的代码如下:

Actor that receive the message: 收到消息的Actor:

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

Actor sending the message: 发送消息的演员:

  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
    // ..
  }

Due to the nature of how value classes work, both your examples will cause the allocation of Feature . 由于值类的工作方式的性质,您的示例都将导致Feature的分配。 Once due to run-time checking in your pattern matching example, and the other due to the signature of receive which requires Any as the input type. 一旦由于模式匹配示例中的运行时检查,另一个由于receive的签名而需要Any作为输入类型。

As the docs for Value Classes specify (emphasis mine): 正如价值类文档指定(强调我的):

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 . 进行运行时类型测试,例如模式匹配

This means that if you're seeing a Vector[_] type, that means your actually passing a concrete vector from some place in the code. 这意味着如果您看到Vector[_]类型,则意味着您实际从代码中的某个位置传递具体向量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM