【问题标题】:Scala: arguments contravariant and return types are covariant why? [duplicate]Scala:参数逆变和返回类型是协变的,为什么? [复制]
【发布时间】:2014-10-14 11:56:20
【问题描述】:

Martin 提到,在 Scala 中的 FP 课程中,参数是“逆变的”,而返回类型是“协变的”。我不认为我完全理解这一点 - 有人可以帮助解决这个问题吗?

【问题讨论】:

    标签: scala covariance contravariance


    【解决方案1】:

    假设 Bonobo 扩展 Animal 并且您有一个 foo 类型为 Animal => Bonobo 的函数。在其他一些地方,你有一个Bonobo => Animal 类型的变量bar。是否应该允许您将foo 分配给bar?当然:

    • foo 只需要一个动物作为参数(与 bar 的预期参数类型 Bonobo 相比,它“太宽”或“太笼统”,因此是逆变的),但它在处理倭黑猩猩时没有问题。李>
    • 你从foo 得到一个倭黑猩猩(与bar 的预期返回类型Animal 相比,它“太窄”或“太特殊”,因此是协变的),但这很好,作为调用者的bar 期望与各种动物打交道

    但是你不能把这个例子反过来,你不能分配一个 Bonobo => Animal 函数,因为这个参数不适合 Animal => Bonobo 函数,因为参数不适合(它可能会得到一个不是倭黑猩猩),并且返回类型也是错误的(你需要一只倭黑猩猩回来,但要得到一只动物,这可能会有所不同)。

    对于所有类似函数的东西(例如方法)都是如此:参数类型是否更通用并且返回类型是否比预期的更特殊并不重要。 “逆变”和“协变”只是这个简单事实的花哨术语。

    【讨论】:

    • +1,这终于让我点击了。在我的脑海中花了一些时间才放弃的一些小故障是:当你有一个需要 Bonobo 的函数时,但你传入了 Animal,你难道不会冒险允许传入不相容的动物吗?但这是脑残。当您将foo 分配给bar 时,bar 的类型仍然是Bonobo -> Animal,因此函数中只允许倭黑猩猩。确实,然后处理倭黑猩猩的 foo 函数完全可以,因为它可以处理动物,而倭黑猩猩就是其中之一。
    猜你喜欢
    • 2017-05-13
    • 2013-11-29
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多