用于协方差的Scala编译器行为

问题描述

以下代码运行良好:

abstract class Vehicle{
  val name:String
}
case class Car(name: String) extends Vehicle
case class Bike(name: String) extends Vehicle

case class Parking[T](vehicle: T)

object Covariance extends App {

  def parkMyVehicle(p : Parking[Vehicle]): Unit = println(s"Parking ${p.vehicle.name}")
  parkMyVehicle(Parking(Car("Mercedes")))
  parkMyVehicle(Parking(Bike("HD")))

}

这有点奇怪,因为Parking不是协变的。

但是,下一行需要协变Parking,否则将不会得到编译(这是预期的)。

parkMyVehicle(Parking[Car](Car("Mercedes")))

我的问题是,为什么parkMyVehicle(Parking(Car("Mercedes")))不要求协变Parking

解决方法

因为可以从上下文中推断出应该是哪种类型。即

parkMyVehicle(Parking(Car("Mercedes")))
//            ^ ---------------------^ What's the type of that?

由于parkMyVehicle使用Parking[Vehicle],所以类型应该来自编译器PoV。这样,表达式就被打上了超类:

parkMyVehicle(Parking[Vehicle](Car("Mercedes"): Vehicle))

如果您提取变量,则将有所不同,但是:

val p = Parking(Car("Mercedes")) // Type is first figured out to be Parking[Car]
parkMyVehicle(p) // now the type of p does not match,so it fails to compile

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...