首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >论点类型不是对位变体吗?

论点类型不是对位变体吗?
EN

Stack Overflow用户
提问于 2012-11-10 12:11:00
回答 4查看 1.8K关注 0票数 18

我理解协方差和对方差这两个术语。但有一件小事我无法理解。在coursera的“Scala中的函数编程”课程中,Martin Ordersky提到:

函数在其参数类型中是反向变量,在返回类型中是协变量。

例如,在Java中,让Dog扩展Animal。让一个功能是:

代码语言:javascript
复制
void getSomething(Animal a){

我的函数调用为

代码语言:javascript
复制
Dog d = new Dog();
getSomething(d)

所以从根本上说,发生的是Animal a = d。根据维基的说法,协方差是“由宽变窄”。在上面,我们从狗变成动物。所以,论点类型不是协变的,而不是反变的吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-11-10 12:27:02

我是Scala中函数的定义

代码语言:javascript
复制
trait Function1 [-T1, +R]  extends AnyRef

在英语中,参数T1是反变的,结果类型R是协变的。什么意思?

当某些代码需要一个Dog => Animal类型的函数时,您可以提供一个Animal => Animal类型的函数,这要归功于参数的对比变化(您可以使用更广泛的类型)。

还可以提供Dog => Dog类型的函数,这要感谢结果类型的协变性(您可以使用更窄的类型)。

这实际上是有道理的:有人想要一个功能,把狗变成任何动物。你可以提供一个转换任何动物(包括狗)的功能。此外,你的功能只能返回狗,但狗仍然是动物。

票数 32
EN

Stack Overflow用户

发布于 2012-11-10 12:15:17

Dog转换为Animal是从窄到宽的转换,所以它不是协方差。

票数 4
EN

Stack Overflow用户

发布于 2012-11-10 12:21:27

我记得我在2007年读Scala书的时候被这句话弄糊涂了。马丁把它说得好像在说语言功能,但在这句话中,他只说了一个关于一般功能的事实。具体来说,Scala简单地通过一个常规特征来建模这个事实。因为Scala有声明-站点的差异,表达这些语义对语言来说是很自然的。

另一方面,Java泛型只支持使用站点方差,因此在Java中最接近函数类型协/反方差的方法是在每个使用站点对其进行手工编码:

代码语言:javascript
复制
public int secondOrderFunction(Function<? super Integer, ? extends Number> fn) {
     ....
}

(假设一个适当声明的接口Function<P, R>P代表参数类型,R代表返回类型)。当然,由于这段代码掌握在客户端,而且根本不特定于函数,所以关于param类型/返回类型差异的语句不适用于Java的任何语言特性。它只在更广泛的意义上适用,涉及职能的性质。

Java 8将引入闭包,这意味着有一流的函数,但是,根据J rg下面的评论,实现将不包括一个成熟的函数类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13321921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档