`::`和`+:`之间有什么区别? [英] What's the difference between `::` and `+:` for prepending to a list)?
问题描述
List
有2种方法,可以指定将元素添加到(不可变的)列表的前面:
List
has 2 methods that are specified to prepend an element to an (immutable) list:
-
+:
(实现Seq.+:
)和 -
::
(仅在List
中定义)
+:
(implementingSeq.+:
), and::
(defined only inList
)
+:
从技术上讲具有更通用的类型签名-
+:
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]
-但忽略了隐式,根据doc消息,只需要将That
设置为List[B]
即可,签名是等效的.
—but ignoring the implicit, which according to the doc message merely requires That
to be List[B]
, the signatures are equivalent.
List.+:
和List.::
有什么区别?如果它们实际上是相同的,我认为根据具体实现List
,最好避免使用+:
.但是,为什么要定义另一个公共方法,客户端代码何时会调用它呢?
What is the difference between List.+:
and List.::
? If they are in fact identical, I assume +:
would be preferred to avoid depending on the concrete implementation 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.
另请参见: Scala列表串联,::: 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)
}
如您所见,对于List
,这两种方法都做同样的事情(编译器将选择
As you can see, for List
, both methods do one and the same (the compiler will choose List.canBuildFrom for the CanBuildFrom
argument).
那么,使用哪种方法?通常,人们会选择接口(+:
)而不是实现(::
),但是由于List
是功能语言中的一种通用数据结构,因此它有自己的被广泛使用的方法. List
的工作方式建立了许多算法.例如,您会发现很多将单个元素放在List
前面的方法,或者调用方便的head
或tail
方法,因为所有这些操作都是O(1)
.因此,如果您在本地使用List
(在单个方法或类内部),则选择List
特定的方法没有问题.但是,如果要在类之间进行通信,即要编写一些接口,则应该选择更通用的Seq
接口.
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. Many algorithms are build up the way how List
works. 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)
. Therefore, if you work locally with a List
(inside of single methods or classes), there is no problem to choose the List
-specific methods. But if you want to communicate between classes, i.e. you want to write some interfaces, you should choose the more general Seq
interface.
这篇关于`::`和`+:`之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!