假设我有一个抽象类A
。我也有类B
和C
从类A
继承。Spark Scala:将子类型传递给接受父类型的函数
abstract class A {
def x: Int
}
case class B(i: Int) extends A {
override def x = -i
}
case class C(i: Int) extends A {
override def x = i
}
鉴于这些类中,我们构建了以下RDD:
val data = sc.parallelize(Seq(
Set(B(1), B(2)),
Set(B(1), B(3)),
Set(B(1), B(5))
)).cache
.zipWithIndex
.map {case(k, v) => (v, k)}
我还具有以下功能得到一个RDD作为输入,并返回每个元素的计数:
def f(data: RDD[(Long, Set[A])]) = {
data.flatMap({
case (k, v) => v map { af =>
(af, 1)
}
}).reduceByKey(_ + _)
}
请注意,RDD正在接受类型A
。现在,我希望val x = f(data)
返回预期的计数,作为B
是子类型的A
,但我得到以下编译错误:
type mismatch;
found : org.apache.spark.rdd.RDD[(Long, scala.collection.immutable.Set[B])]
required: org.apache.spark.rdd.RDD[(Long, Set[A])]
val x = f(data)
这个错误消失,如果我改变函数签名f(data: RDD[(Long, Set[B])])
;但是,我不能这样做,因为我想在RDD中使用其他子类(如C
)。
我也曾尝试以下方法:
def f[T <: A](data: RDD[(Long, Set[T])]) = {
data.flatMap({
case (k, v) => v map { af =>
(af, 1)
}
}) reduceByKey(_ + _)
}
然而,这也给了我以下运行时错误:
value reduceByKey is not a member of org.apache.spark.rdd.RDD[(T, Int)]
possible cause: maybe a semicolon is missing before `value reduceByKey'?
}) reduceByKey(_ + _)
我感谢有这方面的帮助。
仅仅因为B是A的子类型并不代表集[B]设置[A]的亚型。这是因为'Set'是不变的。你需要确保你的集合是一个集合[A] – puhlen