在Scala中A <:B和+ B有什么区别?
有什么区别
[A <: B] 和
 [+B] 
在斯卡拉?
  Q[A <: B]表示Q类可以接受任何B类的子类A 
  Q[+B]表示Q可以取任何类,但如果A是B一个子类,则Q[A]被认为是Q[B]一个子类。 
  Q[+A <: B]表示类Q只能传递B的子类以及传播子类关系。 
 第一个是有用的,当你想要做一些通用的,但你需要依靠B的某些方法。 例如,如果您有一个带有toFile方法的Output类,那么可以在任何可以传入Q类中使用该方法。 
 第二个是有用的,当你想使集合的行为与原始类相同的方式。 如果你拿B并且你创build了一个子类A ,那么你可以在任何需要B地方传递A 但是如果你拿B , Q[B]的集合 ,那么你是否可以总是通过Q[A]而不是? 一般来说,没有; 有些情况下,这是错误的事情。 但是你可以说,通过使用+B (协方差; Q协variables – 跟随 – B的子类的inheritance关系)是正确的。 
我想用一些例子来扩展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() ) 
正如你所看到的名单不关心它是否包含动物或汽车 。 List的开发人员并没有强制执行,例如只有Cars才能进入列表。
另外:
 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]作为parameter passing给函数。  List[Dog]由于List的协方差而被认为是 List[Animal] 一个子类 。 如果List是不变的,它将不起作用。 
现在到types边界:
 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()) ^ */ 
正如你可以看到谷仓是一个只为动物专用的集合 。 没有车在这里允许。
对于我的理解:
第一种是绑定的参数types,在我们的例子中有一个上下限的typebounds,它的types参数A是B(或B本身)的子types。
第二个是类定义的方差注释,在本例中是B的协方差子类
斯卡拉:+ Java:? 扩展T Covariant子类
斯卡拉: – Java:? 超T逆变式子类化
我在研究这个问题的时候发现了这篇博文。 给出了Scala方差的更深层的解释,包括它在分类理论中的理论基础
http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/