如何说明一个特征是否等同于给定类型参数的另一个特征?

时间:2017-02-07 00:39:24

标签: scala generics types traits

我有一个通用的特质

trait MyTrait[T] {

    def apply(t: T): T

    def compose(e: MyTrait[T]): MyTrait[T]
}

另一个针对特定类型实现此特性的特性......

trait IntTrait extends MyTrait[Int] {

    override def compose(e: MyTrait[Int]): MyTrait[Int]
}

现在,即使这不是一件大事,但它主要是美学问题;我希望能说...

trait IntTrait extends MyTrait[Int] {

    override def compose(e: IntTrait): IntTrait
}

但这打破了MyTrait方法的契约,因为它承诺在所有 MyTrait [Int]上定义,而IntTrait,对于所有编译器都知道,只是MyTrait的一个合适的子集[ INT]。所以我希望能够做的就是告诉编译器IntTrait IS MyTrait [Int]。换句话说,没有不是IntTraits的MyTrait [Int]。

我以为我可以通过

来完成这个
trait IntTrait extends MyTrait[Int] {

    type IntTrait = MyTrait[Int]

    override def compose(e: IntTrait): IntTrait
}

哪个有效! ......有点,但如果我试着在其他地方使用这个......

trait doesStuffWithIntTrait {

    def foo: IntTrait
}

然后在实现中,我收到这样的错误......

Type mismatch, expected: IntTrait, actual: IntTrait#IntTrait

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

<img src="planets.gif" width="145" height="126" alt="Planets" usemap="#planetmap"> <map name="planetmap"> <area shape="rect" coords="0,0,82,126" href="sun.htm" alt="Sun"> <area shape="circle" coords="90,58,3" href="mercur.htm" alt="Mercury"> <area shape="circle" coords="124,58,8" href="venus.htm" alt="Venus"> </map> (基于Type mismatch, expected: IntTrait, actual: IntTrait#IntTrait方法)此错误表示您的foo方法返回类型为foo类类型,但您返回类型别名 IntTrait类型(IntTrait)。

IntTrait IS MyTrait [Int]。不是真实的,IntTrait#IntTraitIntTrait子类

为了你的目的,也许你可以这样做:

MyTrait[Int]

答案 1 :(得分:1)

  

所以我希望能够做的就是告诉编译器IntTrait是MyTrait [Int]。换句话说,没有不是IntTraits的MyTrait [Int]。

这些实际上是两种完全不同的欲望。对于第一个,您确实需要一个类型别名,但是它在错误的范围内。删除trait IntTrait,添加

object MyTrait {
  type IntTrait = MyTrait[Int]
}

(如果您还没有object MyTrait)并将其称为MyTrait.IntTrait。您也可以将其放在package object中。

对于第二个,你不能说服编译器,但是遵循@ chengpohi的解决方案(或类似的

trait MyTrait[T, K <: MyTrait[T]] {
  def apply(t: T): T
  def compose(e: K): K
}
trait IntTrait extends MyTrait[Int, IntTrait] {
  override def compose(e: IntTrait): IntTrait
}

)接近了。就其本身而言,它并不会阻止某人声明trait IntTrait2 extends MyTrait[Int, IntTrait2],但您可以MyTrait sealed