0

阿帕奇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-s 对我来说有点黑魔法。

如何修复这段代码,以便sc.broadcast(期望ClassTag)和SizeEstimator.estimate(期望AnyRef)都满意?

4

2 回答 2

3

作为 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)
}
于 2017-06-21T07:54:52.097 回答
2

除了强制隐式之外,您还可以定义T为扩展的类型。请注意,这会将您的版本的使用限制为仅广播 , 的子类(基本上都是非原始的,请参阅http://docs.scala-lang.org/tutorials/tour/unified-types.html):AnyRefClassTagboradcastAnyRef

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
于 2017-06-20T20:42:50.437 回答