我正在尝试创建一些特征列表,由使用 CRTP 的类型参数化,但无法弄清楚如何表达类型约束。这是一些说明问题的示例代码:
trait A[X] {
def x: X
}
trait B[Y <: A[Y]] {
def y(i: Int): Y
}
case class C(i: Int) extends A[C] {
def x = C(i)
}
case class D(i: Int) extends A[D] {
def x = D(i)
}
case class E() extends B[C] {
def y(i: Int) = C(i)
}
case class F() extends B[D] {
def y(i: Int) = D(i)
}
object Program extends App {
def emptyList[X[_ <: Z forSome { type Z <: A[Z] } ]]() = collection.mutable.ListBuffer.empty[X[_]]
val myList = emptyList[B]()
myList += E()
myList += F()
println(myList.map(_.y(2).x))
}
所以在这里我试图创建一个符合 B 特征的对象列表。但是,此代码将无法编译,并给出以下错误:
类型参数 (B) 的种类不符合类型参数的预期种类 (类型 X)。B 的类型参数与 X 类型的预期参数不匹配:类型 Y 的边界 >:Nothing <: A[Y] 比类型 _ 的声明边界更严格 >:Nothing <: Z forSome { type Z <: A[Z] } val myList =空列表[B] ()
对我来说,这似乎_ <: Z forSome { type Z <: A[Z] }
确实至少和我一样严格,Y <: A[Y]
但也许我错过了一些东西。
所以问题是 - emptyList 函数的约束应该是什么才能正确处理 B?