Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何按原样从映射中检索派生类?_Scala_Databricks - Fatal编程技术网

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”很好。