问题标签 [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.
generics - 我该如何处理这个“这不是被覆盖的子类型”错误
我正在尝试在 Kotlin 中编写一些可验证的表单界面。在验证部分我使用https://github.com/kamedon/Validation。
这是我要运行的非常简单的代码;
这段代码给了我;
如果我Validation<out Any>
在 Validatable 中使用它会说;
如果我Validation<in Any>
在 Validatable 中使用它会说;
如果我使用Validation<Any>
而不是Validation<LoginForm>
在 LoginForm 中,代码会运行,但这次内部的名称和年龄validation
是从内部的类中使用的。关于图书馆的使用,我不想改变这一点。
反正有没有一起使用in
和out
关键字,或者可能有另一种方法来实现我的目标。
scala - Scala List map 函数的变化
我有一个问题一直困扰着我。Scala 中的列表是协变的 ( List[+A]
)
假设我们有这些类:
map
函数取List[B]
函数f: B => C
但我也可以使用 af: A => C
它的子类,f: B => C
它完全有意义。
我目前感到困惑的是,该map
函数应该只接受作为原始函数超类的函数(因为函数的参数是逆变的),这不适用于我给出的示例。
我知道我的逻辑有问题,我想开导。
c# - .net 核心中的逆变性如何与 Func 委托一起使用
我有以下代码,我正在尝试为我的域对象编写通用验证规则。在这样做的同时,我有一个问题来处理 Func 代表支持差异
使用上面的代码,编译器会给出一条错误消息说
在线编译器错误:base.AddValidationRule(empPredicate); 参数 1:无法从 'System.Func<>Employee, bool>' 转换为 'System.Func<>Person, bool>
我曾参考过此https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/dd465122%28v%3dvs.100%29但我仍然无法使编译器了解这里的逆变,
感谢您的帮助,以便我更好地理解这一点
scala - 使用扩展方法规避差异检查
这不编译:
好吧,够公平的。但这确实编译:
这让我们可以规避方差检查给我们带来的任何问题:
这感觉像是在作弊。应该避免吗?或者编译器让它滑动有什么正当理由吗?
更新:
考虑一下这个例子:
显然我们已经设法实现了不可能的目标:仍然满足A => Boolean
. 但如果这是不可能的,编译器不应该禁止它吗?
generics - Kotlin 泛型:违反直觉的类型推断和使用 out 关键字检查
我最近一直在学习 Kotlin,同时对协变类型有一些疑问。
示例代码在这里。我有Option
并且Option2
都有一个类型参数T
和一个run
扩展名。
我可以理解 中的前两个run
,validation()
因为它们的行为类似于 Java。但是为什么第三行编译?Option<T>
在 中是不变的T
。我们不能将Option<C>
实例传递到Option<B>
预期的位置。
在我添加一个out
关键字之后T
,现在它们都可以编译了。为什么?
c# - 如何使用受约束的泛型类型参数将类实例化为其派生的接口
以下接口定义了一个数据包。
有两个实现,每个都有自己的附加属性。
以上是我无法控制的库代码。我想为数据包创建一个处理程序
并为具体数据包创建两个实现。
我想将数据包处理程序列表注入到管理数据包处理的类中,以便将来可以使用其他数据包处理程序对其进行扩展。
我遇到的麻烦是在创建注入参数时。我不能做
因为我不能像这样创建一个实例:
我得到错误Cannot implicitly convert type 'FooPacketHandler' to 'IPacketHandler<IPacket>. An explicit conversion exists (are you missing a cast?)
我看了一个类似的问题:Casting generic type with interface constraint。在那个问题中,OP 没有显示接口的成员,只是从泛型的角度来定义它。据我所见,如果我的接口没有使用泛型类型参数作为输入,我可以使用out
关键字使其成为协变的,但这不适用于此处。
如何做到让管理者坚持开闭原则?我唯一的办法是将接口定义更改为
然后在实现中转换为特定的数据包?
c# - 我的协变泛型参数的解决方法是必要的吗?
我从一个简单的通用接口开始:
但是我需要使这个接口的泛型类型协变(出于我不会讨论的原因),但这会导致编译器错误,因为Func<T0,TReturn>
需要T0
逆变(in T0
)或不变参数:
所以我得到这个DoSomething
声明的编译器错误:
错误 CS1961 变化无效:类型参数“TObject”必须在“
IFooContext<TObject>.DoSomething<TValue>(Expression<Func<TObject, TValue>>)
”上始终有效。'TObject' 是协变的。
在向墙上抛出各种想法后,我发现我可以通过移动DoSomething
到非泛型接口并 TObject
在方法上指定其参数来解决此问题,然后将最初预期的方法“公开”为扩展方法,如下所示:
这编译和运行没有任何问题 - 实际用法的语法与我之前示例的预期用法相同。
为什么这行得通,为什么 C# 编译器不能用我原来的单一协变泛型接口在内部为我做这个技巧?
scala - 对于具有类型绑定的逆变类型,隐式解析失败
以下代码编译:
当我们制作T
协变 ( class X[U, +T <: U]
) 时,它也会编译:
当我们制作T
逆变(class X[U, -T <: U]
)时,编译器无法实现implicitly[X[String, String]]
。奇怪的是,它能够实现implicitly[X[Any, Any]]
:
我怀疑尽管有明确的类型注释,但 typeT
处于逆变位置,过早地固定为Any
. 这是预期的行为吗?
奖励点:T
如果我们修复,逆变确实有效U
:
UPDATE1:Dmytro Mitin 回复后更新:
scala - 类型参数化、方差与继承基类的使用
我有一个关于在 Scala 中定义方法/类时何时使用类型参数化与基类类型的问题,特别是当允许的类型在同一层次结构中时 - 使用类型绑定进行约束。
例如:
在上述情况下/通常当将允许的类型限制在某个上限时,我会获得什么优势,NewType
反之亦然NewTypeV2
?他们看起来都和我一样。
据我了解,如果我要添加一些隐式条件检查,例如NewType[T: Addable]
存在于不同层次结构的类型中,那么类型参数化将是有意义的,除了我应该更喜欢类型参数化而不是使用接口类型或基类类型(如案例类成员inTypeA
的类型。NewTypeV2
像 NewType[T] 这样定义类型参数化的方式是否被认为比其他方式更“功能性”?
其次,关于方差与类型界限的问题。在上面的代码块中,NewType 在 Type T 上是不变的,所以 NewType[SubTypeA1] 不是 NewType[TypeA] 的子类型,它们是不相关的,对吗?
如果如上所述我对类型不变性的理解是正确的,那么 testMethod1 是如何编译的?因为我明确地传递了 SubTypeA1 但它仍然被转换为 NewType[TypeA] 并且它可以毫无问题地传递给 testMethod2 。我在这里有什么误解?