问题标签 [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 投票
1 回答
476 浏览

julia - Vector{AbstractString} 函数参数在 julia 中不接受 Vector{String} 输入

Julia 中的以下代码:

给出以下错误:

即使以下代码按预期运行:

此外,AbstractString通常匹配String如下:

Vector{AbstractString}如果我有String元素,如何调用带参数的函数?

0 投票
2 回答
558 浏览

java - 在像 Stream.reduce() 这样的 API 中选择不变性的充分理由是什么?

回顾 Java 8 StreamAPI 设计,我对参数的通用不变性感到惊讶Stream.reduce()

同一个 API 的一个看似更通用的版本可能对 的各个引用应用了协变/逆变U,例如:

这将允许以下情况,目前这是不可能的:

解决方法,使用方法引用将类型“强制”为目标类型:

C# 没有这个特殊问题,Func(T1, T2, TResult)定义如下,使用声明站点差异,这意味着任何使用的 APIFunc都可以免费获得此行为:

与建议的设计相比,现有设计有哪些优势(可能还有 EG 决策的原因)?

或者,换一种方式问,我可能忽略的建议设计的注意事项是什么(例如类型推断困难、并行化约束或特定于归约操作的约束,例如关联性、对未来 Java 声明站点差异的预期BiFunction<in T, in U, out R>, ...)?

0 投票
3 回答
4020 浏览

java - 为什么可以强制转换泛型类?

Java 泛型是不变的,所以不可能进行这样的转换:

但是在第 4 行的以下代码中,我可以转换 from List<Integer>to List<T>,其中T可以是任何类型。为什么允许这种类型的演员表?

我知道它会生成有关未经检查的强制转换的警告,但关键是这种强制转换在参数化方法中是可能的,但在普通代码中是不可能的。请记住,泛型是不变的,为什么允许它?在正常代码中,List<Integer>我只能将其转换List<Integer>为没有意义的转换,而其他转换是非法的。那么在第 4 行中允许这样的转换有什么意义呢?

我知道泛型类型在编译时被删除并以 结尾List xlist = (List)list,但在删除这些类型之前,很明显不应允许这种强制转换,除非它仅在有人通过 Integer 的情况下被接受,因为el这没有多大意义.

0 投票
2 回答
582 浏览

rust - 如何处理 Rust 中的包装器类型不变性?

对包装器类型的引用&Rc<T>和在( is not a even if is a )&Box<T>中是不变的。这个问题的一个具体例子(Rust Playground):T&Rc<T>&Rc<U>TU

此代码导致以下错误:

Box<T>与(Rust Playground )类似的例子(有类似的错误):

在这些情况下,我当然可以只用所需的类型进行注释a,但在许多情况下这是不可能的,因为还需要原始类型。那我该怎么办?

0 投票
1 回答
107 浏览

scala - 为什么用上限的子类参数化的不变泛型类型不符合?

鉴于:

以下是错误的

为什么?

我知道在 Scala 中,泛型类型默认具有非变体子类型。因此,在此示例的上下文中,Invar具有不同类型参数的实例永远不会彼此处于子类型关系。所以 anInvar[ExtendsAnyref]不能用作Invar[AnyRef].

_ <: AnyRef但我对我理解的“AnyRef类型层次结构中的 某种类型”的含义感到困惑。ExtendsAnyref是类型层次结构中的某种类型AnyRef,所以我希望Invar[ExtendsAnyref]符合Invar[_ <: AnyRef].

我知道函数对象的输入参数类型是逆变的,但由于我使用Invar[_ <: AnyRef]而不是Invar[AnyRef]我理解,显然不正确,使用上限将具有“Invar参数化Anyref或其任何扩展”的含义。

我错过了什么?

0 投票
0 回答
2874 浏览

java - Java中“捕获?e”的含义

在 IntelliJ IDEA 中,尤其是当我创建Collection类的实例时,例如:

并尝试键入方法add,IntelliJ 帮助我说出add第一个参数是capture of ? e.

无论如何,我不能使用任何值作为参数,例如:

消息是

add( capture<?>) inCollection不能应用于 ( java.lang.Integer)

这是什么意思?

0 投票
1 回答
1264 浏览

scala - Scala Set,不变类型发生了什么?

在 scala 应用程序中进行重构时,我遇到了从 List 更改为 Set 提出了一个我以前没有的问题的情况。我对方差有一些想法,但我想了解它对编译器的确切含义。

我有类似的东西,它编译和工作得很好:

然后我将列表更改为设置:

在这一点上,创建 MyClassSet 类型的对象不再适合我将 Set 作为参数传递,即使它接受任何 Set 也是如此。现在,当以下工作时,它有点令人困惑(请注意,该集合与之前的 mySet“相同”):

我相信简单的解释是编译器将 mySet val 推断为一个 Set[(String, Boolean)],但是当我直接在 setWorks1 的参数列表中实例化它时,因为它接受一个 Set[Any],所以编译器是将其推断为 Set[Any]。这使得第一个示例失败,第二个示例通过。这些也有效,这表明前一个是正确的:

编译器显示的实际错误是:

列表和集合定义如下:

  • 这种类型差异的差异是否允许我将“比任何类型更受限制的类型”的列表作为参数传递,但在 Set 的情况下不能传递?
  • 这种差异是否只会阻止类型之间的转换或转换?
  • 这主要是编译器“限制”还是不变类型的预期属性?
  • “在实践中”不变类型之间是否还有其他差异,或者它们是否归结为这样的强制转换?
0 投票
1 回答
462 浏览

scala - IntelliJ IDEA:Scala 中的默认参数值

在 Scala REPL 中,我可以将Seq[String]()类型参数用作默认值Seq[T]

在 IDEA 中尝试相同,它抱怨“Seq[String] 不符合预期的类型 Seq[T]”。为什么?

IDEA 抱怨参数默认值的类型问题的屏幕截图

  • IntelliJ IDEA 2016.2.4
  • Scala 插件 2016.2.1
  • 斯卡拉 2.11.7

注 1:对不起,我知道我的示例函数没有多大意义。但是,我的真实(和有用)功能过于复杂,无法在此处发布。

注意 2:起初,示例中的类型名称不是类型T ,而是Any,这不是一个好主意(因为它遮盖了 scala.Any)并引起了一些混乱。因此我解决了这个问题。

0 投票
2 回答
1197 浏览

ocaml - OCaml 方差(+'a,-'a)和不变性

写完这段代码后

我意识到我需要info是可变的。

我写道,然后:

但是,令人惊讶的是,

哦,我记得听说过方差。这是关于协变逆变的东西。我是一个勇敢的人,我会独自发现我的问题!

我发现了这两篇有趣的文章(这里这里),我明白了!

我可以写

但后来我想知道。为什么可变数据类型是不变的而不仅仅是协变的?

我的意思是,我知道 an'A list可以被视为 an 的子类型,('A | 'B) list因为我的列表无法更改。函数也是一样,如果我有一个类型的函数,'A | 'B -> 'C它可以被认为是类型函数的子类型,'A -> 'C | 'D因为如果我的函数可以处理'A并且'B它只能处理'A's,如果我只返回'C's 我可以当然期望'C'D's(但我只会得到'C's)。

但是对于一个数组?如果我有 an'A array我不能将其视为 an('A | 'B) array因为如果我修改数组中的元素放入 a'B那么我的数组类型是错误的,因为它确实是 an('A | 'B) array而不再是 an 'A array。但是 a('A | 'B) array作为'A array. 是的,这很奇怪,因为我的数组可以包含'B但奇怪的是我认为它与函数相同。也许,最后,我并没有完全理解所有内容,但我想把我的想法放在这里,因为我花了很长时间才理解它。

TL;博士

执着的 :+'a

功能 :-'a

可变:不变量('a)?为什么我不能强迫它成为-'a

0 投票
1 回答
174 浏览

scala - SLS3.2.10,这里的不变性有什么问题?

Scala新手在这里遇到问题:

并得到构建时间错误:错误:(12、11)类型不匹配;找到:com.google.common.cache.LoadingCache[Long,String] 必需:com.google.common.cache.LoadingCache[Long,String] 注意:Long <: Long,但 Java 定义的特征 LoadingCache 在类型 K 中是不变的. 您可能希望研究通配符类型,例如_ <: Long. (SLS 3.2.10) .build(

什么是正确的解决方法?为什么代码是错误的?谢谢。