且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

`::`和`+:`之间有什么区别?

更新时间:2022-06-22 05:39:37

确定这两种方法之间差异的***方法是查看源代码.

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前面的方法,或者调用方便的headtail方法,因为所有这些操作都是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.