Ответ 1
Лучший способ определить разницу между обоими методами - посмотреть исходный код.
источник ::
:
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
.