【问题标题】:How to solve type mismatch when compiler finds Serializable instead of the match type?当编译器找到 Serializable 而不是匹配类型时如何解决类型不匹配?
【发布时间】:2015-10-01 01:01:01
【问题描述】:

我有以下解析器来解析包含 Float 和 RDD 的算术表达式:

 import scalaz._
 import Scalaz._

 def term2: Parser[List[\/[Float, RDD[(Int,Array[Float])]]]] = rep(factor2)
 def factor2: Parser[\/[Float, RDD[(Int,Array[Float])]]] = pathxml | num
 def pathxml: Parser[ RDD[(Int,Array[Float])]] = pathIdent ^^ { s => pathToRDD(s)} //pathToRDD is a function that gets the path in string and create an RDD from the file inside that path and pathIdent parse to see whether the input string is a path or not
 def num: Parser[\/[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n => n.left[RDD[(Int,Array[Float])]].toFloat)

得到以下错误:

  [error]  type mismatch;   
  [error]  found   : ParseExp.this.Parser[Serializable]
  [error]  required: ParseExp.this.Parser[scalaz.\/[Float,org.apache.spark.rdd.RDD[(Int, Array[Float])]]]
  [error]   def factor2: Parser[\/[Float, RDD[(Int,Array[Float])]]] = pathxml | num
  [error]                                                                     ^

我是 Scala 新手,不知道如何解决这个错误

【问题讨论】:

    标签: scala parsing rdd type-mismatch scalaz7


    【解决方案1】:

    Serializable(或类似的Product,或两者一起)几乎总是表明您试图将两种类型视为相同的,而实际上它们并非相同。例如:

    scala> if (true) "a" else List(1)
    res0: java.io.Serializable = a
    

    条件表达式的类型是其两个分支类型的最小上限——即分支共有的最具体的类型。这里我们有一个String 和一个List[Int],它们都是AnyRef 的实例,但是除了Serializable 之外没有任何共同点。它们都是Serializable 的事实比它们都是AnyRef 的子类型这一事实更具体,所以这就是推断的类型。

    类似地推断出序列的类型:

    scala> List("a", "b", "c", 'd)
    res1: List[java.io.Serializable] = List(a, b, c, 'd)
    

    一般来说,任何时候你看到Serializable,你都应该开始寻找与其邻居或兄弟类型不同的东西。

    在您的情况下,pathxml | num 将是Parser[RDDThing]Parser[Float \/ RDDThing] 的最小上限,这又是Parser[Serializable]。您应该能够通过将pathxml 提升到您的factor2 定义中的较大类型pathxml.map(_.right) | num 来解决此问题。

    【讨论】:

    • 感谢您的完整解释。我做了建议并更改了代码,我现在收到以下错误:type mismatch found"Product with Serializable" 为什么会这样?!
    • @Rubbic 如果您尝试为pathxml.map(_.right) 添加一个新的(可能是临时的)val,会发生什么?你能输入Parser[Float \/ RDDThing]吗?您可能需要使用 pathxml.map(_.right[Float]) 之类的东西。
    • 如果我添加 "[Float]" 它会给我以下错误: scala.util.Either.RightProjection[Float,org.apache.spark.rdd.RDD[(Int , Array[Float])]] 不带类型参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 2019-09-12
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多