我必须以给定的相应类名作为键来检索存储在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
答案 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)
您不应该手动调用isInstanceOf
和asInstanceOf
,因为这实际上会使编译器丢掉。
您应该改用模式匹配:
opt match {
case Some(c: PreScoreCalculator) => calculationController.calculate(c)
... // Other calculators.
case None => println("Calculator not found.")
}
注意:这基本上与Ichoran相同,我已经在苦恼中说过,我只是将其留在此处记录。