问题标签 [invariance]

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 投票
0 回答
241 浏览

c# - C#中同一列表中的逆变或不变接口

我遇到了一个关于接口协变和逆变的问题。我有两个通用接口:

IConfiguration 只是一个空接口(标记)。还有第三个界面:

我想要一个包含所有 IConfigurable 实现的列表(无论 T 的具体类型如何)。因为 IConfigProvider 是协变的,所以我可以有一个 IConfigProviders 列表,但 IConfigConsumer 是不变的,所以我不能有这样的列表:

最好有一个列表,IConfigurable<IConfiguration>因为我需要在两个接口中定义的功能。

我只是找不到办法做到这一点。

一种解决方法可能是去掉 IConfigConsumer 接口中的 type 参数并定义 Load 方法,如下所示:

但这会稍微“伤害”类型安全性,因为我可以将类型 ConfigA 加载到需要 ConfigB 的 ConfigConsumer 中,并且只有在我尝试在 Load 方法中将其强制转换为 ConfigB 时,它才会在运行时抛出异常。

这是我的完整示例代码:

我开始怀疑我想要的甚至是可能的。你有什么主意吗?预先感谢您的所有帮助!

0 投票
2 回答
385 浏览

scala - Scala - 可变集合中的协变类型

我是 Scala 世界的新手,现在我正在阅读名为“Scala in Action”的书(Nilanjan Raychaudhuri 着),即第 97 页上名为“可变对象需要保持不变”的部分,我不明白以下部分直接取自上述书中。


假设 ListBuffer 是协变的,并且以下代码片段可以正常工作,没有任何编译问题:

你能发现问题吗?因为一切都是 Any 类型,所以您可以将整数值存储到字符串集合中。这是一场等待发生的灾难。为了避免这类问题,让可变对象保持不变总是一个好主意。


我会有以下问题..

1)everything现实中是什么类型?String还是Any?声明是“ val everything: ListBuffer[Any]”,因此我会期望Any,因为一切都应该是类型,Any那么我看不出有Integer任何String问题ListBuffer[Any]。如何将整数值存储到字符串集合中,它们是如何编写的???何为灾难???为什么我应该使用 List(它是不可变的)而不是 ListBuffer(它是可变的)?我看不出有什么区别。我找到了很多答案,可变集合应该具有类型不变,不可变集合应该具有协变类型,但为什么呢?

2)最后一部分“ res4: everything.type = ListBuffer(1, pants)”是什么意思?“everything.type”是什么意思?我猜它everything没有任何方法/函数或变量称为type.. 为什么没有 ListBuffer[Any] 或 ListBuffer[String]?

非常感谢,

安德鲁

0 投票
1 回答
211 浏览

generics - Kotlin 泛型类属性

我知道这似乎是一个重复的问题,但我对不变性、协变和逆变如何工作感到困惑。

我不明白为什么我不能编译这个片段:

我收到类型不匹配错误必需 X 找到列表

但是,如果我将 X 泛型定义为“out”,我将收到一个错误,表明参数 X 在 list1 var 中是不变的。

有人可以帮助另一个迷失在 Kotlin 泛型中的可怜的灵魂吗?

0 投票
0 回答
69 浏览

c# - 为什么这个具体的泛型类型不能被履行相同契约的具体类型所取代?

为什么在实现class Node中泛型类型IEdge<Node>不能被具体实现所取代class Edge:IEdge<Node>

TEdgeN用作输入参数void AddIncoming(TEdgeN edge)以表明在这种情况下out TEdgeN不能解决问题。否则,这可以使用 来解决out TEdgeN,这将允许一个covariant类型TEdgeN

虽然上述,IEdge<NodeGood>对于类型TEdgeN是有效的,我想知道为什么EdgeBad是一个无效的类型TEdgeN,例如:

我完全清楚,我正在监督一些事情,但不应该:

TEdgeN是in的有效类型

我敢肯定,但假设编译器会抱怨,因为解析中INodeIEdge解析时的循环泛型约束NodeBad

  • 要验证NodeBad是 的有效类型TNodeN,它需要知道EdgeBad是 的有效类型TEdgeN
  • 要验证EdgeBad是 的有效类型TEdgeN,它需要知道这NodeBad是 的有效类型TNodeE
  • 要验证NodeBad它是一个有效的类型,TNodeE它需要它是一个有效的类型,TNodeN因为TNodeE它被用作TNodeN约束中的类型interface IEdge
0 投票
1 回答
58 浏览

arrays - 大批: 获取和设置 Int 值而不进行强制转换

我正在构建一个 Matrix 类,并希望能够将Numbers 存储在二维数组中。

这不起作用,因为Array<Number>并且Array<Int>是不变的。我可以通过使用使其工作Array<Array<out Number>>,但 Matrix 将是不可变的,我不希望这样......

强制转换{0 as Int}使编译器错误消失,但这似乎不是一个好主意。我也想做加法之类的事情,我注意到不可能添加Numbers:

那么我该如何解决这个问题呢?为什么我不能添加两个Numbers?

0 投票
1 回答
102 浏览

scala - 在 State 中绕过不变的结果类型

我想定义一个State构建特征的具体子类型的,根据decodeFoo

这不会像 catState中定义的那样type State[S, A]编译,编译器会响应:

decodeBar我可以通过将&的定义扩大decodeBaz到 type 来解决这个问题State[Seq[Byte], Foo]。这是最好的前进方式吗?或者我可以采取不同的方法来避免扩大这些类型吗?

0 投票
1 回答
64 浏览

scala - Scala 类型差异

我有以下代码

所以最后一个错误不是预期的,但是如果我让它A成为协变的,它就会出错,因为我可以说

这很令人困惑,所以我可以接受。

那么此时,如何去掉最后一个错误,让编译器明白 aWarrior是 aPerson呢?

0 投票
4 回答
161 浏览

c# - 无法在列表 c# 中保存通用接口实现

如何使列表包含通用接口的所有不同实现?

例如

我想把所有的捕手放在一个类似的列表中,

我知道这是处理 c# 中的泛型修饰符(协变、逆变和不变性)但无法让它工作的东西。

尝试:在中添加“out”

但给出编译时错误:

“类型参数 'T' 必须在 'ICatcher.Catch(T)' 上逆变有效。'T' 是协变的。”

我究竟做错了什么?

0 投票
1 回答
108 浏览

php - 这是使用 php 7 断言的类不变性的有效示例吗?

我试图更好地理解 Liskov 原则使用的类不变性。

我知道像 D 这样的一些语言对 invariant 有本机支持,但是,在 PHP 中使用断言我尝试将魔法方法和断言结合起来:

  • 我可以使用断言来创建合同吗?
  • BadPerson 是 Liskov 对继承的 Class Invariance 违反的有效示例吗?
  • GoodPerson 是 Liskov 的类不变性的有效例子吗?
0 投票
1 回答
236 浏览

generics - Kotlin 中的方差/协方差泛型

有一个密封类 Result,它被参数化为两种类型 - 成功结果(T)和错误类型(R)。

它由两个类继承:

一个。Success - 数据类,在构造函数中接受对象 T

湾。错误 - 数据类,在构造函数中接受对象 R

我需要创建一个返回 Result 对象的函数。该函数必须以某种方式创建:

  • 该函数的结果可以分配给以下类型的变量:
  • 该函数的结果不能分配给以下类型的变量:

即类 Result 必须在 T 参数上是协变的,在 R 参数上是不变的。