问题标签 [covariant]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
1827 浏览

java - 如何在java中使用桥接技术实现协变方法覆盖

在阅读协变覆盖时,我发现了一个非常奇怪的事实,

协变方法覆盖是使用桥接技术实现的。它还说这个功能是在java5及更高版本中实现的。(我认为这是因为从java5引入的泛型)

它是如何发生的。请帮我举个例子。

0 投票
1 回答
315 浏览

scala - Scala 匿名函数泛型方差问题

我正在学习 Scala 的路上,我很难理解逆变、协变、不变性等。从为什么这个例子不能编译,也就是如何(co-, contra-, and in-)方差工作?我已经了解了如何将函数视为另一个函数的子类型。(知道真的很有用!)

下面的代码是我认为解决我的难题的重要部分。我已经提取了我认为会给问题增加不必要的复杂性的部分。根据示例,我有一个 Student 对象,它将充当工厂来生成函数。

函数将采用 AnyVal 的类型或子类型(Int、Double、Long 等),并且返回输出将具有相同的输入类型。为了实现这一点,学生类接受一个泛型 (A),它是 AnyVal 的子类型。抽象类在那里,因此我可以通过执行类似 List[Master[AnyVal]](Student.func1) 之类的操作来引用这些学生的列表。

问题是我不能有“val function: List[A] => A”这一行,因为我得到错误“协变类型 A 出现在类型 => List[A] => A 的值函数的逆变位置”。我不知道为什么返回类型必须是 A 的逆变器。对于基于 Function1 特征的名称,我在某种程度上可以接受这个事实。

那么我将如何在抽象 Master 类中定义我的函数,以便返回类型是 A 类型的逆变器?我找到了一个如何使用函数定义来定义它的示例(例如 def function[B >: A](v: B): List[B]),但是我将如何使用匿名函数来实现它呢?请记住,主抽象类中的“A”必须是协变的,因为会有一个函数列表接受所有 AnyVal 类型(Int、Double 等)

真的很感谢帮助!让我知道我的任何术语是否关闭。- 斯卡拉学习者

0 投票
1 回答
978 浏览

c# - 学术:在协变泛型中使用基本类型的自动类型推导

我偶然发现 .NET 4.0 MS-C# 编译器的自动类型推导失败,我不得不“手动”指定类型。

这对我来说不是什么大问题,但足以让我好奇为什么编译器不能自动找到调用的正确类型。

我将调用减少到以下程序:

由于最后一次调用 Complex,代码无法编译,标记为“// 3”。

第一个调用简单直接 - 不涉及基类/子类。第二次调用只是“手动”指定所有参数。

我原以为编译器也会自动选择第二次调用中使用的参数来进行第三次调用。当然,第二个参数实际上是“Derived”,但这可以转换为“Base”,第一个参数需要 U 为“Base”类型。由于接口中的协变类型,where 子句应该仍然可以使用“Base”作为 U。

我不确切知道 C# 中泛型类型参数推导的规则,但我一直认为,它的工作原理有点像“如果参数只有一个可能的赋值,就使用这个。如果没有,拒绝编译。”

为什么编译器不自动检测类型?这是其中之一“如果编译器可以做到这一点,那么它也必须能够解决费马大定理” - 案例?:D

0 投票
1 回答
79 浏览

java - 方法返回类型包含子类定义

我想出了一个使用如下语法的代码:

通过查看它,我得到了几个问题。

a) 的返回类型foo(C arg)<A extends B> double[][]? 这是什么意思?例如,我会理解返回类型double[][],但我无法确定前一个修饰符(也许?)做了<A extends B>什么?

b) 为什么返回类型中有子类声明?由于 A 是 B 的子类,我们在哪里覆盖或添加任何方法/成员等?对我来说,它似乎是一个子类,只包含基类 A 的相同方法/成员。不是吗?那么写法有区别public <A> double[][] foo(C arg)吗?

c) 最后,我认为 <> 与 Java 泛型有关,但即便如此,我也看到了类似D<T>which T 用于参数化原始类型的声明D。在这里,我尝试删除 <> (因为我不明白它们代表什么)但编译器抱怨。

0 投票
3 回答
241 浏览

scala - 使用协变类型的私有可变集合

我有一个协变的 Scala 类型Thing[+B]。该实现使用内部可变队列:

private val queue : AsyncQueue[B]()

AsyncQueue 是一个自定义的可变队列实现,具有我无法在不可变版本中轻松实现的特殊属性。因为它是可变的,所以 AsyncQueue 是不变的。所以我不能在我的协变类型中使用它Thing

由于queue是私有的,我可以保证我的代码的正确性:例如,我不会尝试分配queue给 type 的引用Queue[Any]。如何在不使用强制转换的情况下使这项工作保持Thing协变?B

(使用 cast 的解决方案是在 enqueue/dequeue 上声明一个AsyncQueue[Object]和 cast 对象,这非常难看。)

ETA:我了解类型协变,并且我了解为什么我不能声明协变类型的 AsyncQueue 或使 AsyncQueue 本身协变。我的问题是如何设计此代码以避免在任何地方使用强制转换。

0 投票
1 回答
438 浏览

c++ - 具有模板返回类型的虚拟基函数:编译器在以指针类型作为模板参数的派生类中失败 (MSVC 2013)

如果我使用模板参数 T=int* 从 CBaseInterface(参见下面的代码)派生,编译器将失败并出现错误 C2555。用于 T 的所有指针类型都会发生这种情况。如果我改用 typedef,则相同的代码可以正常工作。

指针类型的问题在哪里?我很困惑,我在 Microsoft 的文档中没有找到适合这种情况的任何内容。

希望您能够帮助我。

0 投票
7 回答
1811 浏览

c++ - C++ 中的协变返回类型到底是什么?

尝试执行此操作时出现编译错误:

我假设 A 和 B 是协变类型,因此 A* 和 B* 也应该是(正确的?)通过推论,我本来期望std::vector<A*>并且std::vector<B*>应该是协变的,但事实似乎并非如此。为什么?

0 投票
2 回答
602 浏览

java - 接口、泛型和协变返回类型

假设我有一个如下界面:

现在,是否允许以下​​两种情况?

一方面,我似乎不这么认为,因为Bar2“实现Foo两次”,即使IntegerNumber. 另一方面,这不是协变返回类型 on 的情况doSomething()吗?还是编译器不够聪明,无法检测到这种情况?

0 投票
1 回答
131 浏览

c++ - C++ 类设计:协方差

问题

我想实现一些在图表上工作的算法并返回节点对的分数,指示这些节点是否相似。这些算法应该适用于单个节点对和所有可能的节点对。在后一种情况下,应返回集合/矩阵。

我的方法

算法源自

现在算法在内存使用方面有所不同。一些算法可能是对称的,并且 (u, v) 和 (v, u) 的分数是相同的。这需要返回不同的 ScoreCollection 类型。一个例子是一个稀疏矩阵和一个三角矩阵,它们都从ScoreCollection.

这将归结为协变返回类型:

问题

  • 这种设计方法是解决这个问题的好主意吗?
  • 是否应该公开集合都作为矩阵实现的事实?
0 投票
1 回答
888 浏览

java - Java协变数组不好?

有几个人告诉我,Java 允许协变数组子类型化,换句话说,如果 A 是 B 的子类型,那么 A[] 是 B[] 的子类型,但这是一个不好的特性,因为它会导致运行时错误。有人可以给我一个具体的例子来说明它如何导致运行时错误以及Java是否/如何解决这个问题?