List
具有被指定为一个元件前面加上一个(不可变)列表2种方法:
-
+:
实施Seq.+:
和 -
::
(定义只有在List
)
+:
在技术上有一个更普遍的类型签名工具
def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That
def ::[B >: A](x: B): List[B]
-丁忽略隐式的,它根据该文档信息仅需要That
是List[B]
所述签名是等效的。
是什么区别List.+:
和List.::
? 如果他们实际上是相同的,我相信+:
将是首选,以避免依赖于具体执行List
。 但是,为什么是另一个公共方法定义,而当将客户端代码调用它呢?
编辑
还有一个提取::
在模式匹配,但我想了解一下这些特殊的方法。
另请参见: 斯卡拉连接列表,::: VS ++
以确定这两种方法之间的区别,最好的办法就是看它的源代码。
该源的::
:
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
,这两种方法做同一个(编译器会选择List.canBuildFrom为CanBuildFrom
参数)。
因此,使用哪种方法? 通常人们会选择界面( +:
比实施( ::
),而是因为List
是函数式语言的通用数据结构,它有它自己的方法被广泛使用。 许多算法是建立怎样的方式List
工作。 例如,你会发现很多的前面加上其单一稀土元素的方法List
或拨打方便的head
或tail
的方法,因为所有这些操作都是O(1)
因此,如果你有一个本地工作List
(单一方法或类中),是没有问题的选择List
特异性方法。 但是如果你想类别之间进行通信,例如,你希望写一些接口,你应该选择更一般的Seq
接口。
+:
是更通用的,因为它允许的结果类型是从它被称为上的对象的类型不同。 例如:
scala> Range(1,4).+:(0)
res7: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 2, 3)