当前位置: 首页 > 面试题库 >

参数类型不是协变量吗?

姚晋
2023-03-14
问题内容

我了解协方差和逆方差。但是有一件小事我无法理解。在Coursera的“ Scala中的函数式编程”课程中,Martin Ordersky提到:

函数的参数类型是互变的,而返回类型是协变的

因此,例如在Java中,让Dogextends出现Animal。并让一个函数为:

void getSomething(Animal a){

我有函数调用为

Dog d = new Dog();
getSomething(d)

所以基本上就是这样Animal a = d。根据Wiki,协方差是“从宽到窄转换”。在上面,我们正在从狗变成动物。所以论点类型不是协变而是协变吗?


问题答案:

这是在Scala中定义函数的方式:

trait Function1 [-T1, +R]  extends AnyRef

用英语来说,参数是变量T1,结果类型R是变量。这是什么意思?

当某些代码需要Dog => Animal类型的函数时Animal => Animal,由于参数的矛盾性,您可以提供类型的函数(可以使用更广泛的类型)。

还可以提供Dog => Dog类型的函数,这要归功于结果类型的协方差(可以使用更窄的类型)。

这实际上是有道理的:有人想要将狗转化为任何动物的功能。您可以提供可转换任何动物(包括狗)的功能。同样,您的函数只能返回狗,但是狗仍然是动物。



 类似资料:
  • 问题内容: 给定Date有一个名为“ after(Date)”的方法,而Timestamp有一个名为“ after(Timestamp)”的方法,为什么在以下代码中调用Date中的 after 方法? 至于意外结果有人问在这里。 结果 问题答案: 重载是在编译时考虑的;覆盖在执行时考虑。 时间戳 重载 ,它不会 覆盖 现有方法- 因此您只考虑了中的方法; 而且即使你使用它会 仍然 只使用因为编译时

  • 局部变量 仅在代码块或函数中才可见的变量(参考函数章节的局部变量部分)。 环境变量 会影响用户及shell行为的变量。 一般情况下,每一个进程都有自己的“环境”(environment),也就是一组该进程可以访问到的变量。从这个意义上来说,shell表现出与其他进程一样的行为。 每当shell启动时,都会创建出与其环境对应的shell环境变量。改变或增加shell环境变量会使shell更新其自身的

  • 不同于许多其他编程语言,Bash 并不区分变量的类型。本质上说,Bash 变量是字符串,但在某些情况下,Bash 允许对变量进行算术运算和比较。决定因素则是变量值是否只含有数字。 样例 4-4. 整数还是字符串? #!/bin/bash # int-or-string.sh a=2334 # 整数。 let "a += 1" echo "a = $a "

  • 问题内容: 有人告诉我,Java允许协变数组子类型化,换句话说,如果A是B的子类型,那么A []是B []的子类型,但这是一个不好的功能,因为它可能导致运行时错误。有人可以给我一个具体的例子来说明它如何导致运行时错误,以及Java是否/如何解决此问题? 谢谢! 问题答案: 很简单。 只要您将内容取出,协变类型就不错,但是放入内容的那一刻,整个事情就破裂了。假设您有一个采用Object []作为参数

  • 从Joshua Bloch的Effective Java中, > 数组与泛型类型有两个重要的区别。第一个数组是协变的。泛型是不变的。 协变简单地说,如果X是Y的子型,那么X[]也将是Y[]的子型。数组是协变的,因为字符串是对象的子类型,所以 不变简单地说,不管X是不是Y的子类型, 我的问题是为什么决定在Java中使数组是协变的?还有其他的SO帖子,比如为什么数组是不变的,但是列表是协变的?,但它们

  • 问题内容: Java中的协变返回类型是什么?在一般的面向对象编程中? 问题答案: 协变返回,意味着当一个方法被覆盖时,覆盖方法的返回类型被允许为覆盖方法的返回类型的子类型。 为了举例说明,通常情况是-声明为返回类型。你可以在自己的类中重写此方法,如下所示: 这样做的好处是,任何持有对MyFoo对象的显式引用的方法都将能够调用clone()并知道(无需强制转换)返回值是的实例。如果没有协变量返回类型