Scala 类型差异
Scala type variance
我有以下代码
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) ...
这很混乱,所以我可以接受。
那么此时,如何去掉最后一个错误,让编译器明白一个Warrior
是一个Person
?
如果您的意图是让某些类型 A
能够委托给 A
以及属于 A
子类型的所有类型 B
,那么您可以在没有协方差的情况下实现这一点(注意 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
我有以下代码
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) ...
这很混乱,所以我可以接受。
那么此时,如何去掉最后一个错误,让编译器明白一个Warrior
是一个Person
?
如果您的意图是让某些类型 A
能够委托给 A
以及属于 A
子类型的所有类型 B
,那么您可以在没有协方差的情况下实现这一点(注意 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