Scala 错误的类型推断

Scala wrong type inference

val finalRDD = joinedRDD.map(x => {
          val d1 = x._2._1
          val d2 = x._2._2
          (x._1, d1 + d2)
        })

在上面的代码中,joinedRDD 的类型为 RDD[(Row, (Double, Double))](根据 IntelliJ),而 Scala 编译器说 d1d2AnyVal。 目前,我使用 asInstanceOfd1 & d2 转换为 Double,但下次它说

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double

是 Scala 编译器问题还是 IntelliJ 问题向我显示了错误的推断类型。有什么见解吗?

我觉得不错:-S 类型推断远非无所不知。有时您需要明确指定类型。根据我的经验,当结果类型可以是任何类型时尤其如此。一些尝试:

  1. 我的首选,因为您没有触摸按键:joinedRDD.mapValues(x => x._1 + x._2)
  2. 添加一些类型信息:val d1: Double = x._2._1。运气好的话,至少编译器可能会更明确。
  3. 单独定义你的函数,给参数分配类型,在里面使用if:map(myFunc)

此外,我发现 IntelliJ Scala 插件和实际的 Scala 编译器之间存在一些差异。鉴于您遇到的错误以及 AnyVal 是 Int 和 Double 的常见 parent class 的事实,您很有可能没有双打开始(并且编译器正在尝试找到共享 parent)。仔细检查您是否通过明确提出来获得您提到的类型。很可能你的类型混淆发生在这一行之前。

祝你好运!

嗯,我在 IntelliJ IDEA 14 中尝试过,类型推断是正确的,将 d1 和 d2 识别为 Double(这是预期的)。尽管如此,我通常会避免使用 IDEA 的类型感知突出显示功能,因为很多时候它会变得疯狂并报告虚假结果。

作为旁注,由于您没有更改 RDD 的密钥,请考虑使用 mapValues 而不是 map(这提供了清晰度和性能,因为它会利用输入 RDD 的分区器并在输出 RDD 中重用它)。