如何从Map中检索派生类?

时间:2019-03-22 13:01:10

标签: scala databricks

我必须以给定的相应类名作为键来检索存储在Map中的派生类对象。

如下所示

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
            )

给出键名,我需要从Map获取相应的对象/实例

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.

期望:    执行CalculationController.calculate(opt)

错误:     上面如果条件为假,则不会执行。

那么如何处理这个问题?

如何在下面处理默认的构造函数对象?

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

3 个答案:

答案 0 :(得分:2)

您有一个小错误:

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 :(得分:1)

问题出在

val opt = getCalculatorByOperationName(calcName)

因为它将返回Option[Calculator]而不是Calculator。现在看起来像这样。

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

希望有帮助。

答案 2 :(得分:1)

您不应该手动调用isInstanceOfasInstanceOf,因为这实际上会使编译器丢掉。
您应该改用模式匹配

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

注意:这基本上与Ichoran相同,我已经在苦恼中说过,我只是将其留在此处记录