Scala类型方差

时间:2019-09-06 13:37:49

标签: scala covariance variance contravariance invariance

我有以下代码

class Person
class Warrior extends Person
trait Commander[A] {
  def giveOrder(to: A)
  def delegate(to: Commander[A])
}

val warCommander: Commander[Warrior] = new Commander[Warrior] {
  override def giveOrder(to: Warrior): Unit = ???
  override def delegate(to: Commander[Warrior]): Unit = ???
}

val president: Commander[Person] = new Commander[Person] {
  override def giveOrder(to: Person): Unit = ???
  override def delegate(to: Commander[Person]): Unit = ???
}

warCommander.giveOrder(new Person) // GOOD ERROR: Person is not a Warrior
president.giveOrder(new Person)
warCommander.delegate(president) // GOOD ERROR: Commander[Person] is not a Commander[Warrior]
president.delegate(warCommander) // UNWANTED ERROR: Commander[Warrior] is not a Commander[Person]

所以最后的错误是没有预料到的,但是如果我使A是协变的,则会出错,因为这样我可以说

class Civilian extends Person
val a: Commander[Warrior] = new Commander[Person] { def giveOrder(to: Civilian) ...

这非常令人困惑,所以我可以接受。

因此,在这一点上,如何删除最后一个错误并使编译器理解WarriorPerson

1 个答案:

答案 0 :(得分:1)

如果您打算将某个类型A委托给A以及属于B子类型的所有类型A,则可以实现没有协方差(请注意def delegate[B <: A](to: Commander[B])):

class Person
class Warrior extends Person
trait Commander[A] {
  def giveOrder(to: A)
  def delegate[B <: A](to: Commander[B])
}

val warCommander: Commander[Warrior] = new Commander[Warrior] {
  override def giveOrder(to: Warrior): Unit = ???
  override def delegate[B <: Warrior](to: Commander[B]): Unit = ???
}

val president: Commander[Person] = new Commander[Person] {
  override def giveOrder(to: Person): Unit = ???
  override def delegate[B <: Person](to: Commander[B]): Unit = ???
}

warCommander.giveOrder(new Person) // ERROR: Person is not a Warrior
president.giveOrder(new Person)    // OK
warCommander.delegate(president)   // ERROR: Commander[Person] is not a Commander[Warrior]
president.delegate(warCommander)   // OK