我正在尝试用Java创建一个customRDD。
RDD使用RDD[(K,V)]
中定义的Scala隐式函数PairRDDFunctions[K,V]
将rddToPairRDDFunctions()
转换为object RDD
。
我正在尝试对我的CustomJavaRDD
进行同样的扩展CustomRDD
扩展RDD
。
现在它应该在遇到rddToCustomJavaRDDFunctions()
时调用隐式函数CustomJavaRDD[(K,V)]
,但由于某种原因,它仍然会转到rddToPairRDDFunctions()
。
我做错了什么?
RDD.scala
class RDD[T]
object RDD {
implicit def rddToPairRDDFunctions[K, V](rdd: RDD[(K, V)])
(implicit kt: ClassTag[K], vt: ClassTag[V], ord: Ordering[K] = null):
PairRDDFunctions[K, V] = {
new PairRDDFunctions(rdd)
}
}
CustomRDD.scala
abstract class CustomRDD[T] extends RDD[T]
object CustomRDD {
implicit def rddToCustomJavaRDDFunctions[K,V](rdd: CustomJavaRDD[(K,V)]):
PairCustomJavaRDDFunction[K,V] = {
new PairCustomJavaRDDFunctions[K,V](rdd)
}
}
PairCustomJavaRDDFunctions.scala
class PairCustomJavaRDDFunctions[K: ClassTag, V: ClassTag](self: CustomRDD[(K, V)])
(implicit ord: Ordering[K] = null) {
def collectAsMap() = ???
}
没有错误;程序编译成功,
但是,我要说data: RDD
是CustomJavaRDD
的一个实例。
data.collectAsMap()
在运行时,它将data
转换为PairRDDFunctions
;即它对 RDD.scala 中定义的rddToPairRDDFunctions
进行隐式调用。
但它应该调用 CustomRDD.scala 中定义的rddToCustomJavaRDDFunctions
并将其转换为PairCustomJavaRDDFunctions
。
答案 0 :(得分:1)
但它应该调用 CustomRDD.scala 中定义的
rddToCustomJavaRDDFunctions
并将其转换为PairCustomJavaRDDFunctions
不,Scala根本不会这样工作。你想要什么,根据对象的运行时类型覆盖隐式转换是根本不可能的(在库和你的部分都没有预先存在的机制)。
Implicits是严格的编译时功能。当编译器看到您使用RDD
时,就好像它是PairRDDFunctions
一样,它会在调用RDD.rddToPairRDDFunctions
时进行拼接,就像您自己编写一样。然后,当代码转换为字节码时,该调用已经被烘焙,而没有任何东西可以改变它。没有动态调度,它都是静态的。 rddToCustomJavaRDDFunctions
将被调用的唯一情况是,相关表达式的 static 类型已经是CustomJavaRDD
。
真的,这不应该是必要的。隐式转换实际上只不过是为您节省击键的美化帮助方法。 (隐式参数,现在这些都很有趣。;))应该没有必要覆盖它们,因为辅助方法应该已经是多态的,无论你有RDD
,{{1} },或CustomRDD
。
当然,你可以仍然这样做,但它只会在上述情况下实际做任何事情,这可能不太可能,使整个事情变得毫无意义。