如何确定类型参数的方差? [英] How to determine type parameter's variance?

查看:115
本文介绍了如何确定类型参数的方差?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

>协变和协变的真实示例的启发在Scala中我认为一个更好的问题是:



在设计库时,在确定类型是否存在时应问自己一组特定的问题参数应该是协变还是逆变?还是应该使所有内容不变,然后根据需要进行更改?

解决方案

那么,简单吗,这有意义吗?想想李斯科夫替换。



协方差



如果 A <:B ,传递 C [A] 是否有意义,而 C [B] 是预期的吗?如果是这样,请将其设置为 C [+ T] 。经典示例是不变的 List ,其中 List [A] 可以传递给期望列表[B] ,假设 A B 的子类型。 / p>

两个反例:



可变序列是不变的,因为否则可能会违反类型安全性(在实际上,Java的协变量 Array 容易受此类因素的影响,这就是为什么它在Scala中是不变的。



不变的 Set 是不变的,即使其方法与不变的 Seq 的方法非常相似。区别在于包含,它在集合上键入而在序列上未键入(即接受 Any )。因此,即使可以通过其他方式使其成为协变,也希望在特定方法上增加类型安全性,从而导致选择不变性而不是协变。



相反方差



如果 A< ;: B ,通过 C [B] 在哪里期望 C [A] ?如果是这样,请将其设置为 C [-T] 。可能的经典示例是 Ordering 。尽管一些无关的技术问题阻止了 Order 的反变,但很直观的是,任何可以订购 A 也可以订购 A 。随之而来的是 Ordering [B] ,该命令对所有类型为 B 的类型( A ,可以传递给期望 Ordering [A] 的对象。



尽管Scala的 Ordering 并不是反变量,但 Scalaz 订单是与预期相反。来自Scalaz的另一个示例是它的等于



混合方差?



Scala中混合方差最明显的例子是 Function1 (以及2、3等)。它在接收到的参数中是反变的,在返回的内容中是协变的。但是请注意, Function1 是用于许多闭包的,闭包用于很多地方,这些地方通常是Java使用的地方(或



因此,如果您遇到适用SAM类的情况,则可能是混合使用协方差和协方差的地方。 / p>

Inspired by Real-world examples of co- and contravariance in Scala I thought a better question would be:

When designing a library, are there a specific set of questions you should ask yourself when determining whether a type parameter should be covariant or contravariant? Or should you make everything invariant and then change as needed?

解决方案

Well, simple, does it make sense? Think of Liskov substitution.

Co-variance

If A <: B, does it make sense to pass a C[A] where a C[B] is expected? If so, make it C[+T]. The classic example is the immutable List, where a List[A] can be passed to anything expecting a List[B], assuming A is a subtype of B.

Two counter examples:

Mutable sequences are invariant, because it is possible to have type safety violations otherwise (in fact, Java's co-variant Array is vulnerable to just such things, which is why it is invariant in Scala).

Immutable Set is invariant, even though its methods are very similar to those of an immutable Seq. The difference lies with contains, which is typed on sets and untyped (ie, accept Any) on sequences. So, even though it would otherwise be possible to make it co-variant, the desire for an increased type safety on a particular method led to a choice of invariance over co-variance.

Contra-variance

If A <: B, does it make sense to pass a C[B] where a C[A] is expected? If so, make it C[-T]. The classic would-be example is Ordering. While some unrelated technical problems prevent Ordering from being contra-variant, it is intuitive that anything that can order a super-class of A can also order A. It follows that Ordering[B], which orders all elements of type B, a supertype of A, can be passed to something expecting an Ordering[A].

While Scala's Ordering is not contra-variant, Scalaz's Order is contra-variant as expected. Another example from Scalaz is its Equal trait.

Mixed Variance?

The most visible example of mixed variance in Scala is Function1 (and 2, 3, etc). It is contra-variant in the parameter it receives, and co-variant in what it returns. Note, though, that Function1 is what is used for a lot of closures, and closures are used in a lot of places, and these places are usually where Java uses (or would use) Single Abstract Method classes.

So, if you have a situation where a SAM class applies, that's likely a place for mixed contra-variance and co-variance.

这篇关于如何确定类型参数的方差?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆