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
. Но почему был определен еще один общедоступный метод и когда клиентский код мог его вызвать?
Редактировать
Существует также экстрактор для ::
в сопоставлении с образцом, но меня интересуют именно эти методы.
См. также: Конкатенация списков Scala, ::: vs ++
List.::
на всеобщее обозрение? Похоже, они могли реализовать все вList.+:
, заменив вызов::
в первомcase
наnew scala.collection.immutable.::(elem, this)
. 05.08.2012List
, а не на общийSeq
по причинам, уже объясненным sschaef. Кроме того, согласно этой таблице, существуют огромные различия в том, как каждая реализацияSeq
предназначена для использования. Например,+:
будет ужасно работать сQueue
, а использование::
защитит вас от случайной передачи его вашему алгоритму. 05.08.2012::
. Еще один часто упоминаемый момент заключается в том, что существование::
имеет исторические причины. В первых версиях Scala не было таких обобщенных коллекций, как сегодня. Кроме того, в семействе функциональных языковML
есть:
в качестве оператора добавления к списку. Поэтому его происхождение гораздо глубже, как может показаться. 05.08.2012