加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 函数在其参数类型中是逆变的,在返回类型中是共变量

发布时间:2020-12-16 19:17:13 所属栏目:安全 来源:网络整理
导读:在发布此问题之前,我已经阅读了 this和 this的答案,但我对这个主题的理解仍然有点不清楚,如下所述: 我理解协变和逆变独立意味着什么. 如果我有以下课程: class Car {}class SportsCar extends Car {}class Ferrari extends SportsCar {} 和: object covar
在发布此问题之前,我已经阅读了 this和 this的答案,但我对这个主题的理解仍然有点不清楚,如下所述:

我理解协变和逆变独立意味着什么.

如果我有以下课程:

class Car {}
class SportsCar extends Car {}
class Ferrari extends SportsCar {}

和:

object covar extends App {

    // Test 1: Works as expected

    def test1( arg: SportsCar => SportsCar ) = {
        new SportsCar
    }

    def foo1(arg: Car): Ferrari = { new Ferrari }
    def foo2(arg: SportsCar): Car = { new Ferrari }
    def foo3(arg: Ferrari): Ferrari = { new Ferrari }

    test1(foo1) // compiles
    test1(foo2) // Fails due to wrong return type - violates return type is covariant
    test1(foo3) // Fails due to wrong parameter type - violates param type is contravariant

    // Test 2: Confused - why can I call test2 succesfully with ferrari 
    // as the parameter,and unsuccesfully with a car as the parameter?

    def test2(arg: SportsCar): SportsCar = {
        new Ferrari
    }

    val car = new Car()
    val sportsCar = new SportsCar()
    val ferrari = new Ferrari()

    val f1 = test2(ferrari)  // compiles - why?
    val f2 = test2(car)      // fails - why?

}

如上所述,在测试2中,为什么我可以使用法拉利作为参数成功调用test2,并且以汽车作为参数不成功?

语句Function是否在其参数类型中是逆变的,并且返回类型中的co-variant仅适用于作为参数传递的函数?我想我没有在声明和我写的2个测试之间做出适当的区分.

解决方法

那是因为你将子类型与co / contravariance混合在一起.

在你的第一个例子中,你期望一个Function1 [-T,R].在这种情况下,共同/逆转规则适用于功能类型.在第二个示例中,您遵循简单的子类型规则.

在test1中,传入foo1,即Car =>法拉利一切正常,因为foo1期待一辆车,但得到一辆运动车,这是一辆车.由于子类型的性质,任何需要Car的方法都可以处理子类型.但是当我们单独讨论子类型时,这些规则不起作用.

如果我们用foo1用实际类型扩展test1,也许它会更清晰:

foo1:

>参数类型:

>期望:汽车
>实际:SportsCar

>返回类型:

>期望:SportsCar
>实际:法拉利

一切顺利.

在test2中,规则发生了变化.如果我期待一辆跑车通过任何车,那么我就不能再依赖于跑车的输入而且一切都会中断,但是如果你通过一辆实际上是跑车的法拉利,一切都很好.

再次,让我们排列类型:

测试2:

>第一种情况:

>参数类型:

>期望:SportsCar
>实际:法拉利(子类型)

>结果:大家都很开心

>第二种情况:

>参数类型:

>期望:SportsCar
>实际:汽车

>结果:错误.我们不确定汽车是一辆真正的跑车.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读