如何推广在Array中工作的scala类型



我有以下代码:

trait Vehicle {
def regNumber: String
def lotSize: Int
}
case class Car(regNumber: String) extends Vehicle {override val lotSize = 2}
case class Motorcycle(regNumber: String) extends Vehicle {override val lotSize = 1}
trait AbstractLot[+T <: Vehicle] {
def vehicle: T
def lotSize: Int = vehicle.lotSize
}
final case class CarLot(vehicle: Car) extends AbstractLot[Car]
final case class MotorcycleLot(vehicle: Motorcycle) extends AbstractLot[Motorcycle]

我想要一个ParkingLot类型,它是一个抽象批次的选项数组。但是,当我在下面写代码时,Scala编译器并不高兴

object ParkingLot {
type ParkingLot = Array[Option[AbstractLot[_]]]
//Case 1: OK
def mixMotorcycleCar(motorcycleCapacity: Int, carCapacity: Int): ParkingLot =
Array.fill[Option[MotorcycleLot]](motorcycleCapacity)(None) +: Array.fill[Option[CarLot]](carCapacity)(None)
//Case 2: Not OK
//T is a subclass of AbstractLot. Why isn't this working?
def homogenous[T <: AbstractLot[_]](capacity: Int): ParkingLot = Array.fill[Option[T]](capacity)(None)
//Case 3: Not OK
def carOnly(capacity: Int): ParkingLot = Array.fill[Option[CarLot]](capacity)(None)
}

我做错了什么?我应该如何修复我的代码,以便获得适用于案例2和案例3的ParkingLot类型?

这里的问题是可变集合在Scala中具有不变的元素类型,因此不能在Array[Option[AbstractLot[Any]]]中存储Option[CarLot]Option[MotorcycleLot]元素。原因可以在这里找到:Scala中方差和可变性/不变性之间的关系。

ParkingLot对象主要用于空间预分配,这在Scala中很少需要。您必须重新考虑您的设计,因为不可能创建任何具有协变类型的可变集合。使用可变集合表示停车场的最简单方法如下:

val parkingLot = ArrayBuffer[Vehicle]()
parkingLot.addOne(Car("123"))
parkingLot.addOne(Motorcycle("321"))

最新更新