2013-04-11 15 views
5

Bei zwei Listen a und b, was ist der Unterschied zwischen a ::: b und a ++ b? Ich vermutete, dass eine dieser Betreiber würde einfach die anderen nennen, aber in der Tat sehen die Implementierungen völlig anders:Was ist der Unterschied zwischen ::: und ++ für Listen?

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) 
} 

Von einer Nutzungsperspektive sollte ich lieber a ::: b oder a ++ b? Gibt es aus einer Implementierungsperspektive einen bestimmten Grund, warum einer dieser Betreiber den anderen nicht einfach anruft?

+0

möglich Duplikat von [Scala Liste Verkettung, ::: vs ++] (http://StackOverflow.com/Questions/6559996/Scala-list-Concatenation-VS) –

Antwort

10

Der Unterschied besteht darin, dass Sie nur ::: in 2 Listen verwenden können - dieser Vorgang ist nur für den List-Datentyp verfügbar. Da Listen Sequenzen sind, fungiert er als Verkettungsoperator für Listen.

Die Methode ++ ist allgemeiner - es ermöglicht das Erstellen einer Vereinigung von zwei beliebigen Sammlungen. Das können zwei Mengen sein, in diesem Fall handelt es sich um eine Vereinigung oder zwei Folgen, in diesem Fall handelt es sich um eine Verkettung.

Es gibt keinen semantischen Unterschied zwischen ++ und ::: für 2 Listen - ::: ist die Variante von ++ für funktionelle Listen, die mehr vertraut funktionale Programmierer aussehen sollten.

Die if Aussage, die Sie in der ++ Implementierung sehen, ist eine Optimierung - wenn beide this Sammlung und that Sammellisten sind, verwenden Sie einfach die Liste Konkatenationsoperator ::: zusammen die beiden Listen hinzuzufügen. Verwenden Sie andernfalls die generische Implementierung ++, die alle Elemente von this und that Sammlung zu einem entsprechenden Generator für den Typ That hinzufügt. Der relevante Unterschied für Listen ist also die Performance - für Funktionslisten müssen Sie nicht die zweite Liste durchlaufen, wie eine generische ++ Implementierung - nur die Knoten der ersten Liste müssen neu erstellt werden, um eine neue zu erstellen Funktionsliste.

Verwandte Themen