Scala泛型类型约束和专用行为

Scala泛型类型约束和专用行为,scala,apache-spark,generics,Scala,Apache Spark,Generics,我有一个类,我需要一个apply[T]方法,其中T只能是Foo或Bar。此外,该方法需要根据它是Foo还是Bar而有不同的行为。由于类型擦除,我无法简单地创建apply[Foo]和apply[Bar]方法(这是我的第一次尝试)。为了解决这个问题,我试着这样做 def apply[T](ds: Dataset[T]): Dataset[T] = { ds match { case ds: Dataset[Foo] => ... case ds: Da

我有一个类,我需要一个
apply[T]
方法,其中
T
只能是
Foo
Bar
。此外,该方法需要根据它是
Foo
还是
Bar
而有不同的行为。由于类型擦除,我无法简单地创建
apply[Foo]
apply[Bar]
方法(这是我的第一次尝试)。为了解决这个问题,我试着这样做

def apply[T](ds: Dataset[T]): Dataset[T] = { 
    ds match {
        case ds: Dataset[Foo] => ...
        case ds: Dataset[Bar] => ...
        case _ => ???
    }
}
但这不起作用,因为类型擦除为
t
。此外,这甚至没有将此方法限制为只能使用
Foo
Bar
类型的
t
调用,当它不是这两种类型中的一种时,它只是“不做任何事情”。如何使此apply方法具有这些属性


谢谢。

您可以使用隐式类型类:

trait Baz[T] {
  def apply(ds: DataSet[T]): DataSet[T]
}

implicit val fooImpl = new Baz[Foo] {
  def apply(ds: DataSet[Foo]): DataSet[Foo] = ???
}

implicit val barImpl = new Baz[Bar] {
  def apply(ds: DataSet[Bar]): DataSet[Bar] = ???
}

def apply[T](ds: Dataset[T])(implicit b: Baz[T]): Dataset[T] = b(ds)

下面是一个很好的类型擦除技巧:

def apply(ds: Dataset[Foo]): Dataset[Foo] = ???
def apply(ds: Dataset[Bar])(implicit dummy: DummyImplicit): Dataset[Bar] = ???

允许您拥有具有相同运行时签名的多个方法,而不必使用类型参数。

您仍然需要知道
T
的确切类型,以便在编译时与调用站点上的typeclass的正确实例关联nb:当类型写错时,它不会“什么都不做”,它将抛出一个
NotImplementedError