问题标签 [generic-variance]

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 投票
1 回答
395 浏览

scala - Subtyping between function types

In coursera functional programming course, I came across a subtle concept.

If A2 <: A1 and B1 <: B2, then (A1 => B1) <: (A2 => B2)

Justification

  • when we pass an argument to A2 and because of the subtyping relationship, we can pass the same argument to A1.
  • Then apply the function A1 => B1
  • Then that function gives B1 and because of subtyping that qualifies as B2

If we draw a Venn diagram for this,

  • diagram 1 diagram 1

  • diagram 2 diagram 2

    • Which is the correct diagram for this?
    • How can the result be explained using that Venn diagram ?

Reference : Youtube video

Thanks

0 投票
1 回答
83 浏览

scala - Scala 中的类类型参数。

我很难写出应该很直截了当的东西,但我似乎无法正确使用语法。

我有一个食品类层次结构:

对于动物:

而且我正在尝试在 Animal 中定义一种吃方法,以便熊猫一般不能吃蔬菜,只能吃 Bamboo。目前,我的代码如下所示:

我的麻烦是,当我创建一个蔬菜时,熊猫可以吃它:

所以出了点问题:(

非常欢迎任何帮助:)

0 投票
2 回答
576 浏览

delegates - 为什么 kotlin 不允许协变 mutablemap 成为委托?

我是 Kotlin 的新手。当我学习在地图中存储属性时。我尝试以下用法。

前两个都成功了,最后一个失败了。使用out修饰符,字节码是getName这样的:

正如我们所见,它会导致NullPointerException.

为什么地图委托上不允许逆变?

为什么 kotlin 没有给我编译错误?

0 投票
1 回答
56 浏览

java - 如何实现接受消费者的方法> 在 T 中是逆变的?

在下面的示例中,我可以将 a 传递Consumer<Optional<Integer>foo,但不能传递 a Consumer<Optional<Number>>。另一方面,我可以将任一类型传递给foo2,但是我不能从方法体中调用消费者的接受方法。有没有办法改变foo方法以使其有效?我最初的直觉是尝试void foo(Consumer<Result<? super T>> c),但这显然并不意味着我会假设。

0 投票
1 回答
35 浏览

scala - 类型差异的另一个(更简单)问题

我昨天在这里发布了这个问题的(looong)版本: 类型差异问题

为了缩短(真的)长话短说,这个:

不编译(它抱怨说“P 出现在类型 <: T 类型的 P 中的协变位置”)。对我之前的问题的回答表明该声明确实无效,因为A[Foo, Bar]它将是 的子类A[Nothing, Bar],但后者是非法的(Bar不是 的子类Nothing)。

我不认为这是足够的理由。按照这种逻辑,这样的事情也应该是非法的:class B[+T <: String]-B[String]应该是的子类,B[Any]但后者是无效的。

此外,这:

实际上确实编译。这与上面的内容本质上不一样A吗?

0 投票
1 回答
166 浏览

generics - 当类型参数在声明站点协变时,强制类型参数在使用站点保持不变

我正在构建一个扩展功能KProperty1。该函数需要接受一个扩展属性 ( R) 值类型的参数,即使KProperty1在类型参数中是协变的R

下面是一个稍微人为的例子,尽管我的使用更合理。

似乎编译器正在推断 的类型AnyR这是完全有效的,因为KProperty1<*, String> : KProperty1<*, Any>

我想说的是,对于我的特殊情况,我实际上想要V保持不变。我知道您可以使用outandin作为方差扩大器,但我无法弄清楚如何指定我想在KProperty1这种情况下以不变性覆盖协变注释。

值得注意的是,它适用于KMutableProperty1,因为它在 . 中是不变的R。但是我的代码也需要使用非可变属性。

对于上下文,我正在构建一些生成数据库查询的东西,这就是为什么我需要将值作为属性类型的子类,即使我实际上并没有写入属性,但是这个问题比我的具体问题更普遍,物业处理案。

0 投票
1 回答
2122 浏览

generics - Kotlin:使泛型类型的子类继承函数并限制可用的输出类型

我有以下 Kotlin 类实现类似于 Collections 接口或包含多个元素的集合。

因此,MyCollection 的子类之一的实例描述了某种集合,而 Member<C> 类的实例描述了该集合的特定成员。子类 BigCollection 和 SmallCollection 决定了我们拥有的集合的大小。我的想法是在这里添加更多内容,具体取决于集合的使用难度。

可以想象以下示例

红色可能是 Member< 颜色 > 类型的实例/对象

Persons 可以是 SmallCollection< Persons > 类型的子类型

颜色可以是 BigCollection< 颜色 > 类型的子类型,并且基本上是无限的。这意味着,例如,函数 contains(Member< Color >) 永远不会返回 false,只有 Unsure 或可能 True 如果找到它并在特定超时后抛出异常。

只是为了让您对我正在尝试做的事情有一个基本的了解。

如果我想在编译时和运行时都访问 MyCollection<C> 类型,请注意 JVM 的类型擦除如何迫使我使用递归泛型。

我们可以看到它的类型相当安全。我们知道 mapToOtherDomain 将返回一个 E,它是 MyCollection< D > 的子类型,它与我们输入的函数 (Member< C >) -> Member< E >) 中的 E 类型相同。

现在,如果 MyCollection 的子类可以覆盖函数 mapToOtherCollection,那么大小会反映在函数的静态签名中。函数 f 是一对一的映射,因此如果我们将 A 类型的 smallCollection 映射到 BI,则希望输出是 B 的 smallCollection。

我觉得这应该是可能的,特别是因为它在 Java 中几乎是可能的,而且 Kotlin 应该是 Java 泛型类型系统的扩展。我无法让它工作。我希望它覆盖,但仍然限制返回类型(因此也是输入类型)

我玩过这样的方法签名:

这给编译器错误,它不会覆盖以前的方法,就像这样

它说 Type 参数超出范围。

在这个例子中,如何限制输入/输出类型以更好地匹配泛型类的子类?如果编译器知道 BigCollection 中 contains() 的输出将是静态不确定的,而不是动态不确定的,那也会很整洁。

谢谢

0 投票
2 回答
762 浏览

generics - 如何实现引用符合类型的 Kotlin 接口?

为了进行愚蠢的思想实验,其主要目的是探索语言的一部分是如何工作的,我决定探索一种让 Python 程序员更适应 Kotlin 的方法。简单地说,我可以通过添加:

(除了问题:是否有更通用的方式来指代Foo那里的返回类型,以便如果我更改FooBar,变量类型self仍将引用“此方法的实现类”?)

不得不在每个类中都写上这条线,这样我们才能感到自私地 Python 化,不过这很乏味。所以我转向了一个接口。我最初想要的是类似于 Swift 的Self协议类型。但我在 Kotlin 中找不到类似的东西。在阅读了https://kotlinlang.org/docs/reference/generics.html(这似乎与 Java 和 Kotlin 一样多)之后,我得出结论,也许“声明站点差异”对我来说很重要:

这个更好。我必须在声明中两次列出类名是不可取的,但我认为没有办法解决这个问题。在那儿?

此外,这适用于最终类,但如果我想在根级别有一个符合 Selfish 的类层次结构,事情就会分崩离析:

Bar 中使用self的方法类型错误。添加, Selfish<Bar>会产生冲突。

是否有我尚未发现的工具可以使类型引用继承的类型?

是否有另一种方法(除了接口)来做这样的事情?

我是否使用“声明站点差异”做出了错误的选择?

0 投票
1 回答
54 浏览

c# - 将类型的对象添加到适合泛型类型的对象的通用解决方案

我觉得界面(相反?)方差是答案,但找不到正确的解决方案。

让我们有这些类:

我的情况是:

  • 我有一组已经初始化的香蕉和苹果,比如这两个(但我可以使用不同的):

    /li>
  • 我有一组图片,比如这两个:

    /li>

现在,我试图做一件非常简单的事情,但以一种通用的方式,这意味着我想避免任何开关/ifs,每次找到新水果时我都必须更改代码并且新的 FruitPicture 可能会出现在集合中 =>我想.AddFruit()从我的收藏中选择正确类型的 FruitPicture。我几乎可以更改任何逻辑,但我想保留通用的 FruitPicture 类。

我得到的最接近的是:

谢谢先生。飞碟(开玩笑;有点)

0 投票
2 回答
176 浏览

generics - Kotlin 中的使用站点差异

对于上面提到的代码,我知道这copy function两个类型参数都需要完全相同的类型。稍微修改copy(src: MutableList<T>, dst: MutableList<in T>)一下in关键字,我是说它src 必须是完全类型T,但 destination 可以是 T 的type T任何超类型

对于上述修改后的代码,我可以调用如下方法,

如果我从目的地移除(理解),上述copy(l1, l2)方法不起作用。in

我的问题是,我可以毫无错误地调用该函数我的问题是,如果更新函数参数src以接受out列表的投影。例如

在这种情况下,我无法理解引擎盖下发生了什么。有人可以解释一下吗?

请注意,这只是书中的一个示例。我知道我可以使用List而不是不可变列表src