[英]What's the difference between `::` and `+:` for prepending to a list)?
List
has 2 methods that are specified to prepend an element to an (immutable) list: List
有2个方法,用于将元素添加到(不可变)列表中:
+:
(implementing Seq.+:
), and +:
实现Seq.+:
,和 ::
(defined only in List
) ::
:(仅在List
定义) +:
technically has a more general type signature— +:
技术上具有更一般的类型签名 -
def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That
def ::[B >: A](x: B): List[B]
—but ignoring the implicit, which according to the doc message merely requires That
to be List[B]
, the signatures are equivalent. -丁忽略隐式的,它根据该文档信息仅需要That
是List[B]
所述签名是等效的。
What is the difference between List.+:
and List.::
? List.+:
和List.::
?之间有什么区别? If they are in fact identical, I assume +:
would be preferred to avoid depending on the concrete implementation List
. 如果它们实际上是相同的,我假设+:
最好避免取决于具体的实现List
。 But why was another public method defined, and when would client code call it? 但是为什么定义了另一个公共方法,客户端代码何时会调用它?
There is also an extractor for ::
in pattern matching, but I'm wondering about these particular methods. 还有一个提取::
在模式匹配,但我想了解一下这些特殊的方法。
See also: Scala list concatenation, ::: vs ++ 另请参阅: Scala list concatenation,::: vs ++
The best way to determine the difference between both methods is to look it the source code. 确定两种方法之间差异的最佳方法是查看源代码。
def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)
override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That = bf match {
case _: List.GenericCanBuildFrom[_] => (elem :: this).asInstanceOf[That]
case _ => super.+:(elem)(bf)
}
As you can see, for List
, both methods do one and the same (the compiler will choose List.canBuildFrom for the CanBuildFrom
argument). 如您所见,对于List
,两种方法都是一样的(编译器将为CanBuildFrom
参数选择List.canBuildFrom )。
So, which method to use? 那么,使用哪种方法? Normally one would choose the interface ( +:
) than the implementation ( ::
) but because List
is a general data structure in functional languages it has its own methods which are widely used. 通常会选择接口( +:
::
而不是实现( ::
但由于List
是函数式语言中的通用数据结构,因此它有自己广泛使用的方法。 Many algorithms are build up the way how List
works. 许多算法都是List
工作方式的基础。 For example you will find a lot of methods which prepend single elements to List
or call the convenient head
or tail
methods because all these operations are O(1)
. 例如,您会发现许多方法将单个元素添加到List
或调用方便的head
或tail
方法,因为所有这些操作都是O(1)
。 Therefore, if you work locally with a List
(inside of single methods or classes), there is no problem to choose the List
-specific methods. 因此,如果您在本地使用List
(在单个方法或类中),则选择List
-specific特方法没有问题。 But if you want to communicate between classes, ie you want to write some interfaces, you should choose the more general Seq
interface. 但是如果你想在类之间进行通信,即你想编写一些接口,你应该选择更通用的Seq
接口。
+:
is more generic, since it allows the result type to be different from the type of the object it is called on. +:
更通用,因为它允许结果类型与调用它的对象的类型不同。 For example: 例如:
scala> Range(1,4).+:(0)
res7: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 2, 3)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.