我有一个通用的特质
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
有什么想法吗?
答案 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#IntTrait
是IntTrait
的子类。
为了你的目的,也许你可以这样做:
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
。