【发布时间】:2019-07-24 14:02:02
【问题描述】:
我正在尝试为我正在编写的库构建以下类型结构,但我遇到了类型系统问题。
CarLike
trait CarLike[T, C <: CarLike[T,C]] {
val parts: Seq[T]
def crash(other: C, speed: Int): C
//... other methods
}
SimpleCar
class SimpleCar[T](val parts: Seq[T]) extends CarLike[T, SimpleCar[T]] {
def crash(other: SimpleCar[T], speed: Int) = {
//Some logic to crash with the other car
val newParts = damage(parts) //parts have changed
new SimpleCar(newParts)
}
//...other methods
}
跑车
class SportsCar(val sParts: Seq[String]) extends SimpleCar[String](sParts){
override def crash(other: SimpleCar[String], speed: Int): SimpleCar[String] = {
//Some other logic for crashing a sport car
val newParts = damage(parts) //parts have changed
new SportsCar(newParts)
}
//...other methods
}
崩溃者
case class Crasher[T, C <: CarLike[T,C]](
partsDamager: T => T,
carChecker: C => Seq[T]
/*... more parameters*/
){
def test(cycles:Int) = {
//Some logic to run a crash of two cars
}
}
代码
//...
val crasher = Crasher[String, SportsCar](
(s: String) => s.tail,
(c: SportsCar) => c.parts.filter(p => p.length > 0)
/*Many arguments*/
)
crasher.test(20)
//...
这个想法是让库的用户能够在使用默认的SimpleCar 和实现他自己的CarLike 实现之间进行选择。
此外,用户可以选择汽车零件的类型。在这个简单的示例中,部件是 String,但可以很容易地成为自定义类,可以在自定义类的 crash 方法中使用。
编译时出现如下编译错误:
type arguments [String,my.package.SportsCar] do not conform to method apply's type parameter bounds [T,C <: crashing.CarLike[T,C]]
val crasher = Crasher[String, SportsCar](
很明显,我在这里缺少一些东西。为什么编译器不同意SportsCar 是CarLike 的合法子类型?
【问题讨论】:
-
您可能过于简化了在 SO 上发布的代码。忽略 Crasher 和 Code 部分,我无法让
SportsCar编译,原因可能与您看到的错误相关,也可能不相关. -
@jwvh,谢谢。我实际上编译了我的示例代码,但由于帖子中显示的错误而失败。