2013-04-11 2 views
5

Учитывая два списка a и b, в чем разница между a ::: b и a ++ b? Я подозревал, что один из этих операторов будет просто позвонить другому, но на самом деле, реализации выглядят совершенно иначе:В чем разница между ::: и ++ для списков?

def :::[B >: A](prefix: List[B]): List[B] = 
    if (isEmpty) prefix 
    else if (prefix.isEmpty) this 
    else (new ListBuffer[B] ++= prefix).prependToList(this) 

override def ++[B >: A, That](that: GenTraversableOnce[B]) 
         (implicit bf: CanBuildFrom[List[A], B, That]): That = { 
    val b = bf(this) 
    if (b.isInstanceOf[ListBuffer[_]])(this ::: that.seq.toList).asInstanceOf[That] 
    else super.++(that) 
} 

С точки зрения использования, я должен предпочесть a ::: b или a ++ b? С точки зрения реализации, существует ли конкретная причина, почему один из этих операторов не просто вызывает другой?

+0

Возможный дубликат [Конкатенация списка Scala, ::: vs ++] (http://stackoverflow.com/questions/6559996/scala-list-concatenation-vs) –

ответ

10

Разница заключается в том, что вы можете использовать только ::: в 2 списках - эта операция доступна только для типа данных . Поскольку списки являются последовательностями, он действует как оператор конкатенации для списков.

Метод ++ более общий - он позволяет создать объединение любых двух коллекций. Это может быть два набора, и в этом случае он действует как объединение или две последовательности, и в этом случае он действует как конкатенация.

Там нет семантического различия между ++ и ::: 2 списков - ::: является вариантом ++ функциональных списков, которые должны выглядеть более привычными для функциональных программистов.

if заявление вы видите в ++ реализации является оптимизация - если оба this сбор и that коллекции списки, просто использовать оператор список конкатенации ::: добавить два списка вместе. В противном случае используйте общую реализацию ++, которая добавляет все элементы из коллекции и that соответствующему строителю для типа That.

Соответственно, разница в списках - это производительность - для функциональных списков вам не нужно проходить второй список в качестве общей реализации ++ - только узлы первого списка должны быть восстановлены для создания нового функциональный список.

Смежные вопросы