扩展 class 伴随对象的 Scala 隐式转换
Scala Implicit Conversion for companion object of extended class
我正在尝试在 Java 中创建一个 customRDD。
RDD 使用 object RDD
.
中定义的 Scala 隐式函数 rddToPairRDDFunctions()
将 RDD[(K,V)]
转换为 PairRDDFunctions[K,V]
我正在尝试对扩展 CustomRDD
的 CustomJavaRDD
做同样的事情,扩展 RDD
.
现在它应该在遇到CustomJavaRDD[(K,V)]
时调用隐式函数rddToCustomJavaRDDFunctions()
,但由于某种原因它仍然会转到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)
}
}
自定义RDD.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
.
But it should make call to rddToCustomJavaRDDFunctions
defined in CustomRDD.scala and convert it into PairCustomJavaRDDFunctions
不,Scala 根本无法以这种方式工作。你想要什么,根据对象的运行时类型覆盖隐式转换,这是不可能的(如果库和你的部分都没有预先存在的机制)。
隐式是一个严格的编译时特性。当编译器发现您像使用 PairRDDFunctions
一样使用 RDD
时,它会拼接对 RDD.rddToPairRDDFunctions
的调用,就好像您自己编写的一样。然后,当代码被翻译成字节码时,那个调用已经被嵌入并且没有什么可以改变它。对此没有动态调度,它都是静态的。唯一会调用 rddToCustomJavaRDDFunctions
的情况是当相关表达式的 static 类型已经是 CustomJavaRDD
.
时
真的,这不应该是必要的。隐式转换实际上只不过是美化了的帮助您节省击键次数的辅助方法。 (隐式 参数 ,现在这些很有趣。;))应该没有必要覆盖它们,因为辅助方法应该已经是多态的并且无论你有 RDD
,CustomRDD
, 或 `RDD that travels through time to compute things faster`
.
当然,你还可以,但它只会在上述条件下真正做任何事情,而且这种可能性不大,使整个事情变得毫无意义.
我正在尝试在 Java 中创建一个 customRDD。
RDD 使用 object RDD
.
rddToPairRDDFunctions()
将 RDD[(K,V)]
转换为 PairRDDFunctions[K,V]
我正在尝试对扩展 CustomRDD
的 CustomJavaRDD
做同样的事情,扩展 RDD
.
现在它应该在遇到CustomJavaRDD[(K,V)]
时调用隐式函数rddToCustomJavaRDDFunctions()
,但由于某种原因它仍然会转到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)
}
}
自定义RDD.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
.
But it should make call to
rddToCustomJavaRDDFunctions
defined in CustomRDD.scala and convert it intoPairCustomJavaRDDFunctions
不,Scala 根本无法以这种方式工作。你想要什么,根据对象的运行时类型覆盖隐式转换,这是不可能的(如果库和你的部分都没有预先存在的机制)。
隐式是一个严格的编译时特性。当编译器发现您像使用 PairRDDFunctions
一样使用 RDD
时,它会拼接对 RDD.rddToPairRDDFunctions
的调用,就好像您自己编写的一样。然后,当代码被翻译成字节码时,那个调用已经被嵌入并且没有什么可以改变它。对此没有动态调度,它都是静态的。唯一会调用 rddToCustomJavaRDDFunctions
的情况是当相关表达式的 static 类型已经是 CustomJavaRDD
.
真的,这不应该是必要的。隐式转换实际上只不过是美化了的帮助您节省击键次数的辅助方法。 (隐式 参数 ,现在这些很有趣。;))应该没有必要覆盖它们,因为辅助方法应该已经是多态的并且无论你有 RDD
,CustomRDD
, 或 `RDD that travels through time to compute things faster`
.
当然,你还可以,但它只会在上述条件下真正做任何事情,而且这种可能性不大,使整个事情变得毫无意义.