2016-03-20 13 views
1

In scala replWarum verwenden Sie concat-Operator in scala rückwärts?

scala> List(1) :: 2 
<console>:8: error: value :: is not a member of Int 
      List(1) :: 2 

aber

scala> 2 :: List(1); 
res4: List[Int] = List(2, 1) 

Dies ist unlogisch, da, wenn Infixoperatoren links nach rechts gelesen werden, kann die obige Linie

List(1) :: 2 
List(1).::(2) 

und

übersetzen werden
2 :: List(1) 
2.::(List(1)) 

Ich würde mir vorstellen, eine Int hat keine Methode ::, während eine List tut. Nehme ich etwas falsch an?

+1

Mögliche Duplikat [Was gut sind rechtsassoziativ Methoden in Scala?] (Http: // stackoverflow.com/questions/1162924/what-good-are-right-associative-methods-in-scala) –

Antwort

3

Dies ist unlogisch, da, wenn Infixoperatoren lesen sind von links nach rechts

Wenn man darüber nachdenkt, logisch, ist es viel Sinn macht. Die :: (Nachteile) -Operator Prepends der Wert an den Anfang der Liste, es nicht append es an das Ende der Liste. Wenn man darüber nachdenkt, wie die, die Tatsache, dass der :: Operator rechts assoziative macht Sinn, da es ein Element zu Beginn der List klemmt:

scala> 4 :: List(3,2,1) 
res1: List[Int] = List(4, 3, 2, 1) 

Die interne Implementierung ist ziemlich einfach:

def ::[B >: A] (x: B): List[B] = 
    new scala.collection.immutable.::(x, this) 

List wird intern als LinkedList implementiert, die einen Kopf enthält, der das erste Element in der Sammlung ist, und eine Liste der verbleibenden Elemente, die das heck sind. Deshalb ist das Voranstellen des Elements viel billiger als das Anhängen, da es ein O (n) -Übergehen der internen Liste erfordern würde, um die Elemente zu kopieren, plus das Anhängen des neuen Wertes.

Obwohl teuer, können Sie immer noch mit den :+ Operator, der links assoziativ ist:

scala> List(1,2,3) :+ 4 
res3: List[Int] = List(1, 2, 3, 4) 
2

Scala-Operatoren, die in : enden, sind rechtsassoziativ. In diesem Beispiel versuchen Sie, den Operator :: auf Int anzuwenden.

Auch sind List Strukturen in Scala unveränderlich, so dass das Anhängen an das Ende einer Liste ziemlich teuer ist; Einen Wert am Anfang einer Liste voranzustellen ist sehr günstig.