斯卡拉类型在前面加号

时间:2015-11-06 23:54:11

标签: scala

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]”加号被忽略?

由于

1 个答案:

答案 0 :(得分:4)

类型构造函数参数前面的加号或减号表示该类型的值显示在协变(+)或逆变(-)位置。协变位置意味着类型只发生在&#34;输出&#34;或返回类型,与List的情况一样。如果List[A]List[B],则A <: B的子类型是A,如果Btrait 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如果ABdef test(fun: Dog => String): String = fun(Dog("Jussi")) test { x: Animal => x.food } 的超类型。

Animal => String

在这里,您可以为Dog => String传递+,因为前者是后者的子类型。

方差注释-List[+A]仅出现在类型的定义中,因此在List的定义中,不是使用extends的任何其他位置,例如作为类型归属或在Nothing子句中,因为方差一旦定义就不能改变。这称为定义 - 站点差异。

因为object Nil extends List[Nothing]是Scala中的 bottom 类型,是一种类型,是任何其他类型的子类型,因此我们可以拥有方便的Nil,从而对于任何可能的List[A]A成为Nil的子类型。无论何时需要列表,无论元素类型是什么,都可以使用if (($NameFileJSON != "")&&($VideoId == "")&&($removeVideoId != "")){ $inp = file_get_contents("json/$NameFileJSON.json"); $arr = json_decode($inp); if (($index = array_search($removeVideoId, $arr)) !== false) { echo $index; unset($arr[$index]); } $arr = array_values($arr); $fp_login = fopen("json/$NameFileJSON.json", w); fwrite($fp_login, json_encode($arr)); fclose($fp_login); } print_r(json_encode($arr)