[英]What's the difference between A<:B and +B in Scala?
What's the difference between 有什么区别
[A <: B]
and 和
[+B]
in Scala? 在斯卡拉?
Q[A <: B]
means that class Q
can take any class A
that is a subclass of B
. Q[A <: B]
表示类Q
可以接受任何作为B
的子类的A
类。
Q[+B]
means that Q
can take any class, but if A
is a subclass of B
, then Q[A]
is considered to be a subclass of Q[B]
. Q[+B]
表示Q
可以取任何类,但如果A
是B
的子类,则Q[A]
被认为是Q[B]
的子类。
Q[+A <: B]
means that class Q
can only take subclasses of B
as well as propagating the subclass relationship. Q[+A <: B]
意味着类Q
只能获取B
的子类以及传播子类关系。
The first is useful when you want to do something generic, but you need to rely upon a certain set of methods in B
. 当你想要做一些通用的东西时,第一个是有用的,但你需要依赖B
的某些方法。 For example, if you have an Output
class with a toFile
method, you could use that method in any class that could be passed into Q
. 例如,如果您有一个带有toFile
方法的Output
类,则可以在任何可以传递给Q
类中使用该方法。
The second is useful when you want to make collections that behave the same way as the original classes. 当您想要使集合的行为与原始类相同时,第二个非常有用。 If you take B
and you make a subclass A
, then you can pass A
in anywhere where B
is expected. 如果你拿B
并且你创建了一个子类A
,那么你可以在任何预期B
地方传递A
But if you take a collection of B
, Q[B]
, is it true that you can always pass in Q[A]
instead? 但是如果你收集一个B
, Q[B]
的集合 ,你是否可以总是传入Q[A]
而不是? In general, no; 一般来说,没有; there are cases when this would be the wrong thing to do. 有些情况下这是错误的做法。 But you can say that this is the right thing to do by using +B
(covariance; Q
covaries--follows along with-- B
's subclasses' inheritance relationship). 但你可以说通过使用+B
(协方差; Q
covaries - 跟随 - B
的子类的继承关系)这是正确的做法。
I would like to extend Rex Kerr's excellent answer with some more examples: Let's say we have four classes: 我想用更多的例子来扩展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() )
As you can see List does not care whether it contains Animals or Cars . 如您所见, List并不关心它是否包含动物或汽车 。 The developers of List did not enforce that eg only Cars can go inside Lists. List的开发人员没有强制执行,例如只有汽车可以进入列表。
Additionally: 另外:
case class Shelter(animals: List[Animal]) {}
val animalShelter: Shelter = Shelter( List(new Animal()): List[Animal] )
val dogShelter: Shelter = Shelter( List(new Dog()): List[Dog] )
If a function expects a List[Animal]
parameter you can also pass a List[Dog]
as an argument to the function instead. 如果函数需要List[Animal]
参数,您也可以将List[Dog]
作为参数传递给函数。 List[Dog]
is considered a subclass of List[Animal]
due to the covariance of List. 由于List的协方差,List List[Dog]
被认为是 List[Animal]
的子类 。 It would not work if List was invariant. 如果List不变,它将无法工作。
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())
^
*/
As you can see Barn is a collection only intended for Animals . 正如您所见, Barn是一个仅供动物使用的系列 。 No cars allowed in here. 这里没有车。
I found this blog post while researching this question. 我在研究这个问题时发现了这篇博文。 Gives an even deeper explanation of Scala variance including its theoretical basis in Category Theory 对Scala方差进行了更深入的解释,包括其在范畴论中的理论基础
http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/ http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/
for my Understanding: 对于我的理解:
The first is a parameter type bound, there a upper and lower typebounds in our case its a "type parameter A that is a subtype of B (or B itself). 第一个是参数类型绑定,在我们的例子中有一个上限和下限类型,它是一个“类型参数A,它是B的一个子类型(或B本身)。
The second is a Variance Annotation for a class defintion, in our case a covariance subclassing of B 第二个是类定义的方差注释,在我们的例子中是B的协方差子类
Scala: + Java: ? Scala:+ Java :? extends T Covariant subclassing 扩展T Covariant子类
Scala: - Java: ? 斯卡拉: - Java :? super T Contravariant subclassing super T Contravariant子类
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.