Scala:参数逆变和返回类型是协变的原因吗?

Som*_*kar 0 scala covariance contravariance

在Scala课程的FP中,Martin提到,论证是"逆变",而返回类型是"协变".我不认为我完全理解这一点 - 有人可以帮助这个吗?

Lan*_*dei 8

假设Bonobo扩展Animal,你有一个foo类型的功能Animal => Bonobo.在其他地方你有一个bar类型的变量Bonobo => Animal.如果你被允许分配foobar?当然:

  • foo预计只动物作为参数(这是"太宽的"或"太笼统"相比,预期参数类型Bonobobar,因此逆变),但它没有问题处理倭黑猩猩.
  • 你会得到一个倭黑猩猩从后foo(这是"过于狭隘"或"太特殊"相比,预期收益类型Animalbar,因此协),但是这是好的,为的调用者bar希望处理各种动物

但是你不能转动这个例子,你不能分配一个预期Bonobo => Animal函数的Animal => Bonobo函数,因为参数不适合(它可能得到一个不是倭黑猩猩的动物),并且返回类型是错误的要么(你需要一个倭黑猩猩回来,但得到一个动物,这可能是不同的东西).

这是所有功能状的东西(例如使用的方法)真:如果参数类型都比较一般,并返回类型更特殊的高于预期没关系.对于这个简单的事实,"逆变"和"协变"只是一个奇特的术语.

  • +1,这终于让我满意了。我脑子里的一些小故障花了一些时间才解决,那就是:当你有一个需要“Bonobo”的函数,但你传入了一个“Animal”时,你是否会冒着允许传入不兼容的动物的风险?但这是一个脑残。当您将“foo”分配给“bar”时,“bar”的类型仍然是“Bonobo -> Animal”,因此函数中只允许使用倭黑猩猩。事实上,处理倭黑猩猩的“foo”函数完全能够做到这一点,因为它处理动物,而倭黑猩猩就是其中之一。 (2认同)