我无法理解函数类型1的逆变性。函数类型1的定义如下:
功能1(-T,+ T)
该定义清楚地表明输入类型参数是逆变。因此应该允许类型的超类类型作为参数。但是为什么这会给编译器带来错误。
我已定义以下类
class Animal
class Mammal extends Animal
class Cow extends Mammal
我已经定义了如下方法
def move(m:Mammal) = Unit c
当我调用下面的移动时,它没有错误
move (new Cow)
但这会产生错误
move(new Animal)
为什么我无法使用Animal作为参数调用move(),即使Function1是逆变[-T]。
我是Scala的新手,所以请在此帮助我
答案 0 :(得分:2)
对比度并不意味着该函数可以提供"更低"类型,但在比较两个函数的类型时
type F = Function1(A, B)
type G = Function1(C, B)
如果A
是超级类型C
,则F
是 sub 类型的G
。从本质上讲,函数类型的排序(方差)与输入位置中类型的排序相反(反对)。
特别是如果你想象一个功能:
def foo(f : Cow => String) : String = f(new Cow)
然后从foo
的正文的角度来看,f
可以接受Cow
,但是,从调用者的角度来看,foo
是一个函数,接受Animal
也会接受Cow
就好了,所以允许这样做是合理的:
foo((a : Animal) => "generic animal noise")
foo((c : Cow) => "moo")
在英语中,函数foo
的合同是:
告诉我一件事,当我提供
Cow
时,我会收到一个String
,作为回报,我会给你一个String
。
特别是,当给定Animal
时提供String
的函数符合"当给定Cow
时,返回{{{ 1}}"
答案 1 :(得分:0)
实际上,可以直观地理解其性质:你不能传递动物实例来移动,因为函数移动可能依赖于某些在Mammal中定义但在Animal中缺失的方法。
希望这有帮助