假設我有一個抽象類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