问题标签 [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.
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,
-
- Which is the correct diagram for this?
- How can the result be explained using that Venn diagram ?
Reference : Youtube video
Thanks
scala - Scala 中的类类型参数。
我很难写出应该很直截了当的东西,但我似乎无法正确使用语法。
我有一个食品类层次结构:
对于动物:
而且我正在尝试在 Animal 中定义一种吃方法,以便熊猫一般不能吃蔬菜,只能吃 Bamboo。目前,我的代码如下所示:
我的麻烦是,当我创建一个蔬菜时,熊猫可以吃它:
所以出了点问题:(
非常欢迎任何帮助:)
delegates - 为什么 kotlin 不允许协变 mutablemap 成为委托?
我是 Kotlin 的新手。当我学习在地图中存储属性时。我尝试以下用法。
前两个都成功了,最后一个失败了。使用out
修饰符,字节码是getName
这样的:
正如我们所见,它会导致NullPointerException
.
为什么地图委托上不允许逆变?
为什么 kotlin 没有给我编译错误?
java - 如何实现接受消费者的方法> 在 T 中是逆变的?
在下面的示例中,我可以将 a 传递Consumer<Optional<Integer>
给foo
,但不能传递 a Consumer<Optional<Number>>
。另一方面,我可以将任一类型传递给foo2
,但是我不能从方法体中调用消费者的接受方法。有没有办法改变foo
方法以使其有效?我最初的直觉是尝试void foo(Consumer<Result<? super T>> c)
,但这显然并不意味着我会假设。
scala - 类型差异的另一个(更简单)问题
我昨天在这里发布了这个问题的(looong)版本: 类型差异问题
为了缩短(真的)长话短说,这个:
不编译(它抱怨说“P 出现在类型 <: T 类型的 P 中的协变位置”)。对我之前的问题的回答表明该声明确实无效,因为A[Foo, Bar]
它将是 的子类A[Nothing, Bar]
,但后者是非法的(Bar
不是 的子类Nothing
)。
我不认为这是足够的理由。按照这种逻辑,这样的事情也应该是非法的:class B[+T <: String]
-B[String]
应该是的子类,B[Any]
但后者是无效的。
此外,这:
实际上确实编译。这与上面的内容本质上不一样A
吗?
generics - 当类型参数在声明站点协变时,强制类型参数在使用站点保持不变
我正在构建一个扩展功能KProperty1
。该函数需要接受一个扩展属性 ( R
) 值类型的参数,即使KProperty1
在类型参数中是协变的R
。
下面是一个稍微人为的例子,尽管我的使用更合理。
似乎编译器正在推断 的类型Any
,R
这是完全有效的,因为KProperty1<*, String> : KProperty1<*, Any>
我想说的是,对于我的特殊情况,我实际上想要V
保持不变。我知道您可以使用out
andin
作为方差扩大器,但我无法弄清楚如何指定我想在KProperty1
这种情况下以不变性覆盖协变注释。
值得注意的是,它适用于KMutableProperty1
,因为它在 . 中是不变的R
。但是我的代码也需要使用非可变属性。
对于上下文,我正在构建一些生成数据库查询的东西,这就是为什么我需要将值作为属性类型的子类,即使我实际上并没有写入属性,但是这个问题比我的具体问题更普遍,物业处理案。
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() 的输出将是静态不确定的,而不是动态不确定的,那也会很整洁。
谢谢
generics - 如何实现引用符合类型的 Kotlin 接口?
为了进行愚蠢的思想实验,其主要目的是探索语言的一部分是如何工作的,我决定探索一种让 Python 程序员更适应 Kotlin 的方法。简单地说,我可以通过添加:
(除了问题:是否有更通用的方式来指代Foo
那里的返回类型,以便如果我更改Foo
为Bar
,变量类型self
仍将引用“此方法的实现类”?)
不得不在每个类中都写上这条线,这样我们才能感到自私地 Python 化,不过这很乏味。所以我转向了一个接口。我最初想要的是类似于 Swift 的Self
协议类型。但我在 Kotlin 中找不到类似的东西。在阅读了https://kotlinlang.org/docs/reference/generics.html(这似乎与 Java 和 Kotlin 一样多)之后,我得出结论,也许“声明站点差异”对我来说很重要:
这个更好。我必须在声明中两次列出类名是不可取的,但我认为没有办法解决这个问题。在那儿?
此外,这适用于最终类,但如果我想在根级别有一个符合 Selfish 的类层次结构,事情就会分崩离析:
Bar 中使用self
的方法类型错误。添加, Selfish<Bar>
会产生冲突。
是否有我尚未发现的工具可以使类型引用继承的类型?
是否有另一种方法(除了接口)来做这样的事情?
我是否使用“声明站点差异”做出了错误的选择?
c# - 将类型的对象添加到适合泛型类型的对象的通用解决方案
我觉得界面(相反?)方差是答案,但找不到正确的解决方案。
让我们有这些类:
我的情况是:
我有一组已经初始化的香蕉和苹果,比如这两个(但我可以使用不同的):
/li>我有一组图片,比如这两个:
/li>
现在,我试图做一件非常简单的事情,但以一种通用的方式,这意味着我想避免任何开关/ifs,每次找到新水果时我都必须更改代码并且新的 FruitPicture 可能会出现在集合中 =>我想.AddFruit()
从我的收藏中选择正确类型的 FruitPicture。我几乎可以更改任何逻辑,但我想保留通用的 FruitPicture 类。
我得到的最接近的是:
谢谢先生。飞碟(开玩笑;有点)
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