![](/img/trans.png)
[英]How to replace id type by type parameter in this slick generic DAO trait?
[英]How to state one trait is the equivalent of another generic trait for a given type parameter?
我有一個通用的特質
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 是 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
有任何想法嗎?
Type mismatch, expected: IntTrait, actual: IntTrait#IntTrait
(基於foo
方法)此錯誤意味着您的foo
方法返回類型是IntTrait
類類型,但您返回類型別名 IntTrait
類型( IntTrait#IntTrait
)。
對於IntTrait IS MyTrait [Int]。 不是真的, IntTrait
是MyTrait[Int]
的子類 。
為了你的目的,也許你可以這樣做:
trait MyTrait[T] {
type K <: MyTrait[T]
def apply(t: T): T
def compose(e: K): K
}
trait IntTrait extends MyTrait[Int] {
type K = IntTrait
override def compose(e: IntTrait): IntTrait
}
所以我希望能夠做的就是告訴編譯器IntTrait是MyTrait [Int]。 換句話說,沒有不是IntTraits的MyTrait [Int]。
那些實際上是兩種截然不同的欲望。 對於第一個,您確實需要一個類型別名,但是它在錯誤的范圍內。 刪除trait IntTrait
,添加
object MyTrait {
type IntTrait = MyTrait[Int]
}
(如果你還沒有object MyTrait
)並將其稱為MyTrait.IntTrait
。 您也可以將它放在包對象中 。
對於第二個,你不能說服編譯器,但是遵循@ 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
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.