有什么区别

[A <: B]

[+B]

在Scala?

有帮助吗?

解决方案

Q[A <: B] 意味着该课程 Q 可以参加任何课程 A 那是一个子类 B.

Q[+B] 意思是 Q 可以采取 任何 班级,但如果 AB, , 然后 Q[A] 被认为是 Q[B].

Q[+A <: B] 意味着该课程 Q 只能参加 B 以及传播子类关系。

当您想执行通用的事情时,第一个很有用,但是您需要依靠一系列方法 B. 。例如,如果您有 Output 上课 toFile 方法,您可以在可以传递到的任何类中使用该方法 Q.

当您想制作与原始类相同的收藏时,第二个很有用。如果你服用 B 你做了一个子类 A, ,那么你可以通过 A 在任何地方 B 是期待。但是,如果您服用 收藏B, Q[B], ,您总是可以传递吗? Q[A] 反而?通常,不;在某些情况下,这是错误的事情。但是您可以说这是正确的选择 +B (协方差; Q 协变量 - 与 -B的子类的继承关系)。

其他提示

我想扩展 雷克斯·克尔(Rex Kerr)的出色答案 还有一些例子:假设我们有四个类:

 class Animal {}
 class Dog extends Animal {}

 class Car {}
 class SportsCar extends Car {}

让我们从差异开始:

 case class List[+B](elements: B*) {} // simplification; covariance like in original List

 val animals: List[Animal] = List( new Dog(), new Animal() )
 val cars: List[Car] = List ( new Car(), new SportsCar() )

如你看到的 列表不在乎它是否包含动物还是汽车. 。列表的开发人员没有强制执行,例如,只有汽车才能进入列表。

此外:

case class Shelter(animals: List[Animal]) {}

val animalShelter: Shelter = Shelter( List(new Animal()): List[Animal] )
val dogShelter: Shelter = Shelter( List(new Dog()): List[Dog] )

如果功能期望 List[Animal] 参数您也可以通过 List[Dog] 作为函数的参数。 List[Dog] 被认为是 List[Animal] 由于清单的协方差。如果列表不变,则行不通。

现在进入类型范围:

case class Barn[A <: Animal](animals: A*) {}

val animalBarn: Barn[Animal] = Barn( new Dog(), new Animal() )
val carBarn = Barn( new SportsCar() )
/* 
error: inferred type arguments [SportsCar] do not conform to method apply's type parameter bounds [A <: Animal]
    val carBarn = Barn(new SportsCar())
                 ^
*/

如你看到的 谷仓是一个仅针对动物的收藏品. 。这里不允许汽车。

为了理解:


第一个是绑定的参数类型,在我们的情况下,上部和较低的类型是“类型参数A,它是B(或B本身)的子类型。


第二个是对班级定义的差异注释,在我们的情况下,B的协方差子类别


Scala: + Java:?扩展T协变量子类

Scala:-java:?超级T逆转子类

我在研究这个问题时找到了这篇博客文章。对Scala差异提供了更深入的解释,包括其在类别理论中的理论基础

http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top