如何从地图中检索派生的 类?

How to retrieve derived classes as is from a Map?

我必须检索存储在地图中的派生 class 对象,给定相应的 class 名称作为键。

如下图

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

中获取相应的 object/instance
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

这里的问题在

val opt = getCalculatorByOperationName(calcName)

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

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

希望对您有所帮助。

你有一个小错误:

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) > 然后你会看到 class.

您不应该手动调用 isInstanceOf & asInstanceOf,因为这基本上是在丢弃编译器。
您应该使用 模式匹配 代替:

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

注意:这基本上是同一个 Ichoran,我已经在 gitter 中说过,我只是把它留在这里作为记录