泛型类型参数相对于抽象类型成员的一个优点似乎是前者可以等同,例如:
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 }
但是,抽象类型成员是否可能出现类似于第二种情况的情况?以下解决方案不起作用,因为无法从自身类型定义中引用类型“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
}
最佳答案
您可以使用类型参数相等的见证,=:=
或 scalaz.Leibniz.===
(这是更通用的,但意味着取决于在 scalaz 上)。
class C extends A with B { type Z; val w1: X =:= Z; val w2: Y =:= Z }
如果类型不相等,则无法实例化它,您可以使用 w1
和 w2
来“转换”类型为 X 的值
或 Y
来输入 Z
。
关于scala - Scala 中是否可以等于抽象类型成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26348723/