问题标签 [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.
julia - Vector{AbstractString} 函数参数在 julia 中不接受 Vector{String} 输入
Julia 中的以下代码:
给出以下错误:
即使以下代码按预期运行:
此外,AbstractString
通常匹配String
如下:
Vector{AbstractString}
如果我有String
元素,如何调用带参数的函数?
java - 在像 Stream.reduce() 这样的 API 中选择不变性的充分理由是什么?
回顾 Java 8 Stream
API 设计,我对参数的通用不变性感到惊讶Stream.reduce()
:
同一个 API 的一个看似更通用的版本可能对 的各个引用应用了协变/逆变U
,例如:
这将允许以下情况,目前这是不可能的:
解决方法,使用方法引用将类型“强制”为目标类型:
C# 没有这个特殊问题,Func(T1, T2, TResult)
定义如下,使用声明站点差异,这意味着任何使用的 APIFunc
都可以免费获得此行为:
与建议的设计相比,现有设计有哪些优势(可能还有 EG 决策的原因)?
或者,换一种方式问,我可能忽略的建议设计的注意事项是什么(例如类型推断困难、并行化约束或特定于归约操作的约束,例如关联性、对未来 Java 声明站点差异的预期BiFunction<in T, in U, out R>
, ...)?
java - 为什么可以强制转换泛型类?
Java 泛型是不变的,所以不可能进行这样的转换:
但是在第 4 行的以下代码中,我可以转换 from List<Integer>
to List<T>
,其中T
可以是任何类型。为什么允许这种类型的演员表?
我知道它会生成有关未经检查的强制转换的警告,但关键是这种强制转换在参数化方法中是可能的,但在普通代码中是不可能的。请记住,泛型是不变的,为什么允许它?在正常代码中,List<Integer>
我只能将其转换List<Integer>
为没有意义的转换,而其他转换是非法的。那么在第 4 行中允许这样的转换有什么意义呢?
我知道泛型类型在编译时被删除并以 结尾List xlist = (List)list
,但在删除这些类型之前,很明显不应允许这种强制转换,除非它仅在有人通过 Integer 的情况下被接受,因为el
这没有多大意义.
rust - 如何处理 Rust 中的包装器类型不变性?
对包装器类型的引用&Rc<T>
和在( is not a even if is a )&Box<T>
中是不变的。这个问题的一个具体例子(Rust Playground):T
&Rc<T>
&Rc<U>
T
U
此代码导致以下错误:
Box<T>
与(Rust Playground )类似的例子(有类似的错误):
在这些情况下,我当然可以只用所需的类型进行注释a
,但在许多情况下这是不可能的,因为还需要原始类型。那我该怎么办?
scala - 为什么用上限的子类参数化的不变泛型类型不符合?
鉴于:
以下是错误的
为什么?
我知道在 Scala 中,泛型类型默认具有非变体子类型。因此,在此示例的上下文中,Invar
具有不同类型参数的实例永远不会彼此处于子类型关系。所以 anInvar[ExtendsAnyref]
不能用作Invar[AnyRef]
.
_ <: AnyRef
但我对我理解的“AnyRef
类型层次结构中的 某种类型”的含义感到困惑。ExtendsAnyref
是类型层次结构中的某种类型AnyRef
,所以我希望Invar[ExtendsAnyref]
符合Invar[_ <: AnyRef]
.
我知道函数对象的输入参数类型是逆变的,但由于我使用Invar[_ <: AnyRef]
而不是Invar[AnyRef]
我理解,显然不正确,使用上限将具有“Invar
参数化Anyref
或其任何扩展”的含义。
我错过了什么?
java - Java中“捕获?e”的含义
在 IntelliJ IDEA 中,尤其是当我创建Collection
类的实例时,例如:
并尝试键入方法add
,IntelliJ 帮助我说出add
第一个参数是capture of ? e
.
无论如何,我不能使用任何值作为参数,例如:
消息是
add(
capture<?>
) inCollection
不能应用于 (java.lang.Integer
)
这是什么意思?
scala - Scala Set,不变类型发生了什么?
在 scala 应用程序中进行重构时,我遇到了从 List 更改为 Set 提出了一个我以前没有的问题的情况。我对方差有一些想法,但我想了解它对编译器的确切含义。
我有类似的东西,它编译和工作得很好:
然后我将列表更改为设置:
在这一点上,创建 MyClassSet 类型的对象不再适合我将 Set 作为参数传递,即使它接受任何 Set 也是如此。现在,当以下工作时,它有点令人困惑(请注意,该集合与之前的 mySet“相同”):
我相信简单的解释是编译器将 mySet val 推断为一个 Set[(String, Boolean)],但是当我直接在 setWorks1 的参数列表中实例化它时,因为它接受一个 Set[Any],所以编译器是将其推断为 Set[Any]。这使得第一个示例失败,第二个示例通过。这些也有效,这表明前一个是正确的:
编译器显示的实际错误是:
列表和集合定义如下:
- 这种类型差异的差异是否允许我将“比任何类型更受限制的类型”的列表作为参数传递,但在 Set 的情况下不能传递?
- 这种差异是否只会阻止类型之间的转换或转换?
- 这主要是编译器“限制”还是不变类型的预期属性?
- “在实践中”不变类型之间是否还有其他差异,或者它们是否归结为这样的强制转换?
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
?
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(
什么是正确的解决方法?为什么代码是错误的?谢谢。