1

我有一个通用类型:

trait BaseTrait[T <: BaseTrait[T]] {
  self: T =>
  def similar(that: T): Float

}

具体类型:

class MyConcrete(val..) extends BaseTrait[MyConcrete]  {
  type Self = MyConcrete
..
  def similar(that: MyConcrete) = {
     return 0.5f // dummy
  }
}

我想写这样的东西:

def create[T <: BaseTrait[T]](..): T = new MyConcrete(..)

我得到错误:

type mismatch;  found: MyConcrete  required: T  

我期待由于 MyConcrete 是 BaseTrait 的子类型,它会起作用(但我错了)

我的意图是隐藏 MyConcrete 的构造,以便以后可以将上面的内容更改为 MyConcrete2(它也像 MyConcrete 一样扩展 BaseTrait),并且只关心 BaseTrait 接口的代码不会受到我的更改的影响。

如何编写我的 create 方法的接口。

谢谢。

4

1 回答 1

1
def create[T <: BaseTrait[T]](..): T = new MyConcrete(..)

该类型参数T没有多大意义。您要求调用者告诉方法是什么T,这显然在这种情况下不起作用。如果您要解释T为从方法返回的东西(自动推断),那么调用者仍然无法使用它。

从调用者的角度来看,你能得到的最好的就是

def create(..): BaseTrait[_] = new MyConcrete(..)

另一方面,如果您想要一个特定的子类型但隐藏 的实现MyConcrete,您将定义一个特征

trait ConcreteLike extends BaseTrait[ConcreteLike]

class MyConcrete extends ConcreteLike {
  def similar(that: ConcreteLike) = 0.5f
}

def create(): ConcreteLike = new MyConcrete()
于 2013-10-23T17:09:28.380 回答