Scala中的列表 - 加上冒号与双冒号(+:vs::)

时间:2016-12-27 14:00:40

标签: scala

我对可用的+:::运算符感到有些困惑。

看起来他们两个都给出了相同的结果。

scala> List(1,2,3)
res0: List[Int] = List(1, 2, 3)

scala> 0 +: res0
res1: List[Int] = List(0, 1, 2, 3)

scala> 0 :: res0
res2: List[Int] = List(0, 1, 2, 3)

对于我的新手来说,这两种方法的源代码看起来相似(加上冒号方法在使用构建器工厂时对泛型有额外的条件)。

应该使用以下哪种方法?

1 个答案:

答案 0 :(得分:19)

+:适用于任何类型的集合,而::List的具体实现。 如果您仔细查看+:的{​​{1}},您会注意到,当预期的返回类型为::时,它实际上会调用List。这是因为::更有效地实现了List:它只是将新头连接到现有列表并返回结果,这是一个恒定时间操作,而不是线性复制+:的一般情况下的整个集合。

另一方面,

+:需要CanBuildFrom,所以你可以做一些事情(尽管在这种情况下看起来不太好),例如:

val foo: Array[String] = List("foo").+:("bar")(breakOut)

(在这种特殊情况下,这是非常无用的,因为你可以从所需的类型开始,但你的想法是你可以在一个集合中添加和元素,并在一个“go”中改变它的类型,避免额外的拷贝)。