【发布时间】:2014-10-14 11:56:20
【问题描述】:
Martin 提到,在 Scala 中的 FP 课程中,参数是“逆变的”,而返回类型是“协变的”。我不认为我完全理解这一点 - 有人可以帮助解决这个问题吗?
【问题讨论】:
标签: scala covariance contravariance
Martin 提到,在 Scala 中的 FP 课程中,参数是“逆变的”,而返回类型是“协变的”。我不认为我完全理解这一点 - 有人可以帮助解决这个问题吗?
【问题讨论】:
标签: scala covariance contravariance
假设 Bonobo 扩展 Animal 并且您有一个 foo 类型为 Animal => Bonobo 的函数。在其他一些地方,你有一个Bonobo => Animal 类型的变量bar。是否应该允许您将foo 分配给bar?当然:
foo 只需要一个动物作为参数(与 bar 的预期参数类型 Bonobo 相比,它“太宽”或“太笼统”,因此是逆变的),但它在处理倭黑猩猩时没有问题。李>
foo 得到一个倭黑猩猩(与bar 的预期返回类型Animal 相比,它“太窄”或“太特殊”,因此是协变的),但这很好,作为调用者的bar 期望与各种动物打交道但是你不能把这个例子反过来,你不能分配一个 Bonobo => Animal 函数,因为这个参数不适合 Animal => Bonobo 函数,因为参数不适合(它可能会得到一个不是倭黑猩猩),并且返回类型也是错误的(你需要一只倭黑猩猩回来,但要得到一只动物,这可能会有所不同)。
对于所有类似函数的东西(例如方法)都是如此:参数类型是否更通用并且返回类型是否比预期的更特殊并不重要。 “逆变”和“协变”只是这个简单事实的花哨术语。
【讨论】:
Bonobo 的函数时,但你传入了 Animal,你难道不会冒险允许传入不相容的动物吗?但这是脑残。当您将foo 分配给bar 时,bar 的类型仍然是Bonobo -> Animal,因此函数中只允许倭黑猩猩。确实,然后处理倭黑猩猩的 foo 函数完全可以,因为它可以处理动物,而倭黑猩猩就是其中之一。