在 Scala 中编写带有 ClassTag 和 AnyRef 约束的泛型函数
Writing a generic function with ClassTag and AnyRef constraints in Scala
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
-s 对我来说有点黑魔法。
如何修复这段代码,使 sc.broadcast
(期望 ClassTag
)和 SizeEstimator.estimate
(期望 AnyRef
)都满意?
除了强制执行隐式 ClassTag
之外,您还可以将 T
定义为扩展 AnyRef
的类型。请注意,这会将您的 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
作为 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)
}
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
-s 对我来说有点黑魔法。
如何修复这段代码,使 sc.broadcast
(期望 ClassTag
)和 SizeEstimator.estimate
(期望 AnyRef
)都满意?
除了强制执行隐式 ClassTag
之外,您还可以将 T
定义为扩展 AnyRef
的类型。请注意,这会将您的 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
作为 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)
}