Apache SparkContext
有一个方法:
def broadcast[T: ClassTag](value: T): Broadcast[T]
我正在尝试编写一个分析数据的包装器(现在它只是尝试记录大小)并调用原始方法:
def broadcast[T: ClassTag](value: T): Broadcast[T] = {
val sizeEst = SizeEstimator.estimate(value)
log.debug(s"Broacasting $sizeEst bytes of data")
sc.broadcast(value)
}
org.apache.spark.util.SizeEstimator
需要AnyRef
,因此我收到错误消息。我对Scala并不是特别有经验,所以ClassTag
- 对我来说有点黑魔法。
如何修复此代码段,以便sc.broadcast
(期望ClassTag
)和SizeEstimator.estimate
(期望AnyRef
)都满意?< / p>
答案 0 :(得分:2)
除了强制执行隐式T
之外,您还可以将AnyRef
定义为扩展ClassTag
的类型。请注意,这会将您的boradcast
版本的使用限制为仅广播AnyRef
的子类(基本上都是非基元,请参阅http://docs.scala-lang.org/tutorials/tour/unified-types.html):
def broadcast[T <: AnyRef : ClassTag](value: T): Broadcast[T] = {
val sizeEst = SizeEstimator.estimate(value)
log.debug(s"Broacasting $sizeEst bytes of data")
sc.broadcast(value)
}
broadcast(List(1,2,3)) // compiles
broadcast("str") // compiles
broadcast(1) // does not compile, because Int does not extend AnyRef
答案 1 :(得分:2)
作为Tzach Zohar答案的替代方案:由于通用T
无论如何都会被装箱,这实际上是asInstanceOf
不存在任何问题的罕见情况:
def broadcast[T: ClassTag](value: T): Broadcast[T] = {
val sizeEst = SizeEstimator.estimate(value.asInstanceOf[AnyRef])
log.debug(s"Broacasting $sizeEst bytes of data")
sc.broadcast(value)
}