这里 :ClassTag : 不允许在特征上使用 TypeTag 基类定义,因为它们被视为上下文边界
我可以让它成为抽象类,但我失去了多重继承的好处
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]
}
这是因为
Scala 不允许 trait 接收参数,因为它们没有构造函数(这可能会在不久的将来发生变化)。上下文边界的扩展是向定义添加隐式参数。因此,您实际上是在尝试编写:
trait DataProcessor[T <: Product, U <: Product](implicit ev: ClassTag[T], ev1: TypeTag[U], ...)
相反,您可以要求它们作为特征上的抽象类型成员:
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]
}
或者,正如 Luis 提到的,在方法级别将隐式移动到实际需要它们的位置:
def performAnalysis(inputDs: Dataset[T])(implicit ev: ClassTag[T], ev1: TypeTag[T]): Dataset[U]