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]”加号被忽略?
由于
答案 0 :(得分:4)
类型构造函数参数前面的加号或减号表示该类型的值显示在协变(+
)或逆变(-
)位置。协变位置意味着类型只发生在"输出"或返回类型,与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
是def 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)
。