Сопоставление с классами значений в Akka

Я создал 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("_")
  }

Когда я выполняю код, хотя я отправляю 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[_] выполнен.

Документация Акки упоминает:

Рекомендованный способ создания экземпляров свойств акторов использует отражение во время выполнения для определения правильного конструктора актера, который должен быть вызван, и из-за технических ограничений не поддерживается, когда указанный конструктор принимает аргументы, являющиеся классами значений. В этих случаях вы должны либо распаковать аргументы, либо создать реквизит, вызвав конструктор вручную:

Но не упоминайте ничего о сопоставлении с 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
    // ..
  }

1 ответ

Решение

Из-за особенностей работы классов значений оба ваших примера приведут к выделению Feature, Один раз из-за проверки во время выполнения в вашем примере сопоставления с образцом, а другой из-за подписи receive что требует Any в качестве типа ввода.

Как указано в документах для классов значений (выделено мое):

Сводка распределения

Класс значения фактически создается, когда:

  • класс значения рассматривается как другой тип.
  • класс значений присваивается массиву.
  • делать тесты типов во время выполнения, такие как сопоставление с образцом.

Это означает, что если вы видите Vector[_] тип, это означает, что вы фактически передаете конкретный вектор из некоторого места в коде.

Другие вопросы по тегам