Как извлечь производные классы из карты? - PullRequest
2 голосов
/ 22 марта 2019

Мне нужно получить производные объекты класса, хранящиеся на карте, с указанием имени соответствующего класса в качестве ключа.

Как показано ниже

trait Caluclator
class PreScoreCalculator(data:Seq[Int]) extends Caluclator
class BenchMarkCalculator(data:Seq[Int]) extends Caluclator


val calculatorsLookUp:Map[String, Calculator]  = Map[String, Calculator](
            "PreScore" -> new PreScoreCalculator,
             "BenchMark" -> new BenchMarkCalculator
            )

Учитывая имя ключа, мне нужно получить соответствующий объект / экземпляр с карты

def getCalculatorByOperationName(operation:String) : Option[ Calculator]  = {
       calculatorsLookUp.get(operation)
    }

Я звоню, как показано ниже

   val calcName = "PreScore"

   val opt = getCalculatorByOperationName(calcName) 

   if(opt.isInstanceOf[PreScoreCalculator] )   /// this is coming as false
      calculationController.calculate(opt)     // this is not being executed.

Ожидайте: Выполнить вычисленияController.calculate (opt)

Ошибка: Выше, если условие ложно, следовательно, не выполняется.

Так, как справиться с этой проблемой?

Как работать с объектами конструктора по умолчанию?

class PreScoreCalculator(data:Seq[Int]) extends Caluclator

Ответы [ 3 ]

2 голосов
/ 22 марта 2019

У вас есть небольшая ошибка:

opt относится к типу Option[Calculator]

В Scala хороший способ справиться с сопоставлением с образцом:

opt match {
    case Some(calculator: PreScoreCalculator) =>
      calculationController.calculate(calculator)
    case _ => // nothing to do
  }

Или сделайте это более декларативным способом:

  opt.filter(_.isInstanceOf[PreScoreCalculator])
      .foreach(calculationController.calculate)

Однако использование instanceOf является чем-то вроде анти-паттерна.

Как совет:

Используйте println(opt.getClass)> тогда вы увидите класс.

1 голос
/ 22 марта 2019

Вы не должны вызывать isInstanceOf & asInstanceOf вручную, потому что это в основном отбрасывает компилятор.
Вы должны использовать сопоставление с шаблоном вместо:

opt match {
   case Some(c: PreScoreCalculator) => calculationController.calculate(c)
   ... // Other calculators.
   case None => println("Calculator not found.")
}

Примечание: Это в основном тот же Ichoran, и я уже сказал в gitter, я просто оставляю это здесь для записи .

1 голос
/ 22 марта 2019

Проблема здесь на

val opt = getCalculatorByOperationName(calcName)

, потому что он вернет Option[Calculator], а не Calculator. Теперь это будет выглядеть так ...

if(opt.map(_.isInstanceOf[PreScoreCalculator]).getOrElse(false))
  calculationController.calculate(opt.get)

Надеюсь, это поможет.

...