Scala RDD的解决方法不是协变的

时间:2014-05-22 16:53:45

标签: scala types covariance apache-spark

我试图编写一个函数来操作RDD [Seq [String]]对象,例如:

def foo(rdd: RDD[Seq[String]]) = { println("hi") }

无法在RDD [Array [String]]:

类型的对象上调用此函数
val testRdd : RDD[Array[String]] = sc.textFile("somefile").map(_.split("\\|", -1))
foo(testRdd)

->
error: type mismatch;
found   : org.apache.spark.rdd.RDD[Array[String]]
required: org.apache.spark.rdd.RDD[Seq[String]]

我想这是因为RDD不是协变的。

我已经尝试了很多关于foo的定义来解决这个问题。其中只有一个编译过:

def foo2[T[String] <: Seq[String]](rdd: RDD[T[String]]) = { println("hi") }

但它仍然被打破了:

foo2(testRdd)


->
<console>:101: error: inferred type arguments [Array] do not conform to method foo2's type
parameter bounds [T[String] <: Seq[String]]
          foo2(testRdd)
          ^
<console>:101: error: type mismatch;
found   : org.apache.spark.rdd.RDD[Array[String]]
required: org.apache.spark.rdd.RDD[T[String]]

知道如何解决这个问题吗?这一切都发生在Spark shell中。

1 个答案:

答案 0 :(得分:9)

为此,您可以使用view bound

Array不是Seq,但可以查看Seq

def foo[T <% Seq[String]](rdd: RDD[T]) = ???

<%表示T可以被视为Seq[String],因此,只要您在Seq[String]上使用T方法,就T将被转换为Seq[String]

要将Array[A]视为Seq[A],需要在范围内设置隐式函数,以便将Array转换为Seq s。正如IonuţG. Stan所说,它存在于scala.Predef