Scala 为什么在Function1[-A,+;B]中将第一个类型参数定义为逆变?
全部 在阅读了Daniel Spiewak提供的答案以及《Scala编程》一书的第19.3-19.7节之后,我对Function1[-A,+B]的定义产生了另一个困惑:为什么它的第一个类型参数是逆变的?我有一个原因,就是这个类型参数保证了当有多个情况时,子类型总是比超类型出现得早,同时,子类型“是”一个超类型。例如:Scala 为什么在Function1[-A,+;B]中将第一个类型参数定义为逆变?,scala,Scala,全部 在阅读了Daniel Spiewak提供的答案以及《Scala编程》一书的第19.3-19.7节之后,我对Function1[-A,+B]的定义产生了另一个困惑:为什么它的第一个类型参数是逆变的?我有一个原因,就是这个类型参数保证了当有多个情况时,子类型总是比超类型出现得早,同时,子类型“是”一个超类型。例如: class A class B extends A class C extends B scala> val withDefault: A => B = {
class A
class B extends A
class C extends B
scala> val withDefault: A => B = {
| case x:B => new B
| case x:A => new B }
withDefault: A => B = <function1>
A类
B类扩展了A类
C类扩展到B类
scala>val,默认值为:A=>B={
|案例x:B=>新的B
|案例x:A=>new B}
默认情况下:A=>B=
这里,(1)
情况x:B
早于情况x:A
,(2)函数1[A,B]与模式匹配无关。这就是为什么函数类型的参数类型是相反的。考虑这个函数:
def doHigherOrder(handleAnyAnimal: Animal => T,
anyAnimal: Animal ): T = {
// ...foo...
handleAnyAnimal(anyAnimal)
// ...bar...
}
如果函数是协变的而不是逆变的,那么函数Duck=>T
也将是Animal=>T
的子类型,您可以执行doHigherOrder(handleAnyDuck)
。这将是一个错误,因为在doHigherOrder
中,handleAnyImal(anyAnimal)
表达式(在运行时/计算时)将归结为handleAnyDuck(anyAnimal)
,这显然是不对的,因为可以处理任何Duck
的函数可能无法处理任何动物
:
def doHigherOrder(handleAnyDuck: Duck => T,
anyAnimal: Animal ): T = {
// ...foo...
handleAnyDuck(anyAnimal) // <-- ERROR
// ...bar...
}
比照
val x = handleDuck(animal) // <-- ERROR
val y = handleAnimal(duck) // ok
val x=handleDuck(动物)//
val x = handleDuck(animal) // <-- ERROR
val y = handleAnimal(duck) // ok
val x = handle(duck = animal) // <-- ERROR
val y = handle(animal = duck ) // ok