协方差的 Scala 编译器行为
Scala compiler behaviour for Covariance
以下代码 运行 完美:
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
以下代码 运行 完美:
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