无法理解功能1(-T1,+ T1)的逆变

时间:2015-11-08 07:29:37

标签: scala

我无法理解函数类型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的新手,所以请在此帮助我

2 个答案:

答案 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中缺失的方法。

希望这有帮助