作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
sealed trait List[+A] // `List` data type, parameterized on a type, `A`
case object Nil extends List[Nothing] // A `List` data constructor representing the empty list
/* Another data constructor, representing nonempty lists. Note that `tail` is another `List[A]`,
which may be `Nil` or another `Cons`.
*/
case class Cons[+A](head: A, tail: List[A]) extends List[A]
我的问题是A前面的“+”是什么?为什么这里“List[A]”的加号被忽略了?
谢谢
最佳答案
类型构造函数参数前面的加号或减号表示该类型的值出现在协变(+
)或逆变(-
)位置。协变位置意味着该类型仅作为“输出”或返回类型出现,如 List
的情况。 .然后是 List[A]
是 List[B]
的子类型如果 A <: B
, 如果 A
是 B
的子类型:
trait Animal { def food: String }
case class Dog(name: String) extends Animal { def food = "all" }
def test(xs: List[Animal]) = xs.map(_.food)
test(List(Dog("Jussi")))
在这里您可以传递 List[Dog]
对于 List[Animal]
因为List[Dog] <: List[Animal]
.
逆变是相反的——类型只作为输入出现。例如 Function1[A, Out] <: Function1[B, Out]
如果 A >: B
, 如果 A
是 B
的父类(super class)型.
def test(fun: Dog => String): String = fun(Dog("Jussi"))
test { x: Animal => x.food }
在这里您可以传递 Animal => String
对于 Dog => String
因为前者是后者的子类型。
方差注释+
或 -
只出现在类型的定义中,所以在 List[+A]
的定义中,而不是其他任何地方List
被使用,例如作为类型归属或在 extends
子句,因为方差一旦定义就不能改变。这称为定义站点差异。
因为Nothing
是 Scala 中的 bottom 类型,是任何其他类型的子类型,因此我们可以方便地使用 object Nil extends List[Nothing]
,从而Nil
成为 List[A]
的子类型对于任何可能的A
.每当需要列表时,无论是什么元素类型,都可以使用 Nil
.
关于scala 类型,前面有加号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33577410/
我是一名优秀的程序员,十分优秀!