Сопоставление с классами значений в 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[_]
тип, это означает, что вы фактически передаете конкретный вектор из некоторого места в коде.