为什么traits不具有Context Bounds的参数

skj*_*ini 2 generics scala

这里:ClassTag:Trait上不允许使用TypeTag基类定义,因为它们被视为Context Bounds

我可以使它成为抽象类,但我失去了多继承的好处

import scala.reflect.ClassTag
import reflect.runtime.universe.TypeTag
import org.apache.spark.sql.Dataset

trait DataProcessor[T <: Product : ClassTag : TypeTag, U <: Product : ClassTag : TypeTag] {
  def performAnalysis(inputDs: Dataset[T]): Dataset[U]
}
Run Code Online (Sandbox Code Playgroud)

Yuv*_*kov 6

这是因为Scala不允许特征接收参数,因为它们没有构造函数(这可能会在未来发生变化).上下文边界的扩展是向定义添加隐式参数.因此,你实际上是在尝试写:

trait DataProcessor[T <: Product, U <: Product](implicit ev: ClassTag[T], ev1: TypeTag[U], ...)
Run Code Online (Sandbox Code Playgroud)

相反,您可以要求它们作为特征上的抽象类型成员:

trait DataProcessor[T <: Product, U <: Product] {
  def typeTagU: TypeTag[U]
  def clsTagU: ClassTag[U]
  def typeTagT: TypeTag[T]
  def clsTagT: ClassTag[T]

  def performAnalysis(inputDs: Dataset[T]): Dataset[U]
}
Run Code Online (Sandbox Code Playgroud)

或者,正如Luis所提到的,在方法级别将隐含移动到您实际需要它们的位置:

def performAnalysis(inputDs: Dataset[T])(implicit ev: ClassTag[T], ev1: TypeTag[T]): Dataset[U]
Run Code Online (Sandbox Code Playgroud)