为什么特征不能具有上下文边界参数

时间:2019-01-28 16:47:46

标签: scala generics

此处: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]
}

1 个答案:

答案 0 :(得分:6)

这是由于以下事实:Scala不允许特征接受参数,因为它们没有构造函数(这可能是change in the upcoming future)。上下文边界的扩展是在定义中添加隐式参数。因此,您实际上是在尝试编写:

trait DataProcessor[T <: Product, U <: Product](implicit ev: ClassTag[T], ev1: TypeTag[U], ...)

相反,您可以在特征上将它们要求为abstract type members

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]