Scala 如何按原样从映射中检索派生类?
我必须检索存储在映射中的派生类对象,并将相应的类名作为键 如下所示Scala 如何按原样从映射中检索派生类?,scala,databricks,Scala,Databricks,我必须检索存储在映射中的派生类对象,并将相应的类名作为键 如下所示 trait Caluclator class PreScoreCalculator(data:Seq[Int]) extends Caluclator class BenchMarkCalculator(data:Seq[Int]) extends Caluclator val calculatorsLookUp:Map[String, Calculator] = Map[String, Calculator](
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.
期望:
执行calculationController.Calculation(opt)
错误:
如果条件为false,则不会执行
那么如何处理这个问题呢
如何处理以下对象,即默认构造函数对象
class PreScoreCalculator(data:Seq[Int]) extends Caluclator
问题出在这里
val opt = getCalculatorByOperationName(calcName)
因为它将返回选项[Calculator]
而不是计算器
。现在看起来是这样的
if(opt.map(_.isInstanceOf[PreScoreCalculator]).getOrElse(false))
calculationController.calculate(opt.get)
希望有帮助。您有一个小错误:
opt
属于类型Option[计算器]
在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)
>然后你就会看到这个类。你不应该手动调用isInstanceOf
&asiinstanceof
,因为这基本上就是把编译器扔掉。您应该使用模式匹配:
opt match {
case Some(c: PreScoreCalculator) => calculationController.calculate(c)
... // Other calculators.
case None => println("Calculator not found.")
}
注意:这基本上是相同的Ichoran,我在gitter中已经说过,我只是将此记录在这里。感谢您的及时回复,很抱歉,即使密钥未预存,也会一直执行此操作。println(opt.getClass)给出了“classscala.Some”,你说得对,对不起,我修正了我的答案,现在测试了这两种情况;)非常感谢,为什么在这里使用foreach?我在这里迭代什么?
opt
属于Option[Calculator]
类型。如果你想用它做点什么,你必须打开它,使用它>foreach
做到这一点-检查选项的API
。谢谢你的澄清,如果我的PrecoreCollector采用了一个构造函数,即PrecoreCollector(数据:Seq[Int])。在上面的场景中,如何处理它?谢谢,我可以知道你为什么使用.map吗?如果不是。isInstanceOf[PreStoreCalculator]如果键不是“PreStore”,则返回false,对吗?为什么我们需要。getOrElse(错误)??好的。首先,opt
的结果始终是Option[Calculator]
,Scala的Predef对象提供了一个隐式转换,允许您将key->value作为该对(key,value)的替代语法写入。如果结果为“无”,那么它将转到.getOrElse(false)
,这样它是安全的。米格尔·梅加·苏亚雷斯非常感谢您让我的PrecoreCalculator更加清晰,如果我的PrecoreCalculator采用了一个构造函数,即PrecoreCalculator(数据:Seq[Int]),如何处理它,在上述场景中?@Miguel Mejia Suarez您能推荐一本学习scala应用程序设计和最佳实践的好书吗?@Shyam您能详细说明一下吗?您是否也需要提取该Seq
?附言:你能修改计算器的代码吗?或者那些是你无法控制的吗?@Shyam从技术上讲,这不是一个要求书籍/课程推荐的地方。。。但是,既然这是一个评论,而不是一个问题本身,我想也不算太糟糕。当然每个人都会有不同的想法,但我真的很喜欢《Scala编程》(书)和《Scala函数编程》(Coursera专业化)作为开始。过了一段时间(大多数人建议有一年的经验)开始学习FP“猫的Scala”很好。