泛型类型参数优于抽象类型成员的优点似乎是前者可以等于,例如:
trait A[X]
trait B[Y]
trait C[Z] extends A[Z] with B[Z]
类似地:
trait C[Z] {
self: A[Z] with B[Z] =>
}
类型参数的赋值事实上说三件事:X = Z,Y = Z,因此X = Y.
第一种情况可以类似地表示:
trait A { type X }
trait B { type Y }
class C extends A with B { type X = Z; type Y = Z; type Z }
但是,抽象类型成员可能会出现第二种情况吗?以下解决方案自#type;" Z"不能从自我类型定义中引用,它本身必须首先出现:
trait C {
self: A with B { type X = Z; type Y = Z } =>
type Z
}
奇怪的是,即使" b"的类型要求,以下似乎也可以编译。显然是违反了:
trait C2 {
val a: A { type X = Z }
val b: B { type Y = Z }
type Z
}
class A2 extends A { type X = Int }
class B2 extends B { type Y = String }
class D extends C2 {
override val a = new A2
override val b = new B2
type Z = Int
}
答案 0 :(得分:1)
您可以使用类型参数相同的见证,=:=
或scalaz.Leibniz.===
(更通用,但取决于scalaz)。
class C extends A with B { type Z; val w1: X =:= Z; val w2: Y =:= Z }
如果类型不相等,则无法实例化此问题,您可以使用w1
和w2
来“转换”X
或{{1}类型的值输入Y
。