如何从Map中检索派生类?

问题描述 投票:1回答:3

给定相应的类名作为键,我必须检索存储在Map中的Derived类对象。

如下图所示

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.

期望:执行calculateController.calculate(opt)

错误:如果条件为false则上面因此没有执行。

那么如何处理这个问题呢?

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

class PreScoreCalculator(data:Seq[Int]) extends Caluclator
scala databricks
3个回答
1
投票

你不应该手动调用isInstanceOfasInstanceOf,因为这基本上是在抛弃编译器。 您应该使用模式匹配:

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

注意:这基本上和Ichoran一样,我已经在gitter中说了,我只是留在这里记录。


2
投票

你有一个小bug:

optOption[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
投票

这里的问题是

val opt = getCalculatorByOperationName(calcName)

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

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

希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.