[英]Scala type variance
I have the following code 我有以下代码
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]
So the last error is not expected but if I make A
to be covariant it errors out because then I could say 所以最后的错误是没有预料到的,但是如果我使A
是协变的,那么它就会出错,因为那我可以说
class Civilian extends Person
val a: Commander[Warrior] = new Commander[Person] { def giveOrder(to: Civilian) ...
which is very confusing, so I can accept that. 这非常令人困惑,所以我可以接受。
So at this point, how to remove the last error and let the compiler understand that a Warrior
is a Person
? 因此,在这一点上,如何删除最后一个错误并使编译器了解Warrior
是Person
?
If your intention is for some type A
to be able to delegate to A
and all types B
that are a subtype of A
, then you can achieve that without covariance (note the def delegate[B <: A](to: Commander[B])
): 如果您打算让某种类型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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.