[FIXED] Was bedeutet Punkt Doppelpunkt Doppelpunkt (.::) in Scala?

Ausgabe

Der folgende Code fügt der resListe ein Element hinzu. Meine Frage ist, wie scala .::Symbole intern übersetzt?

Code-Auszug:

var res = List[(Int, Int)]()
res .::= (1, 2)
res .::= (3, 4)
res

Ausgang:

res56: Liste[(Int, Int)] = Liste((1,2),(3,4))

Lösung

In diesem Snippet passieren einige Dinge. Bevor wir darauf eingehen, lassen Sie uns über den Unterschied zwischen varund sprechen val. Nämlich, dass eine mit dem valSchlüsselwort deklarierte Variable unveränderlich ist, dh ihr Wert kann nicht geändert werden:

scala> val x = 1
x: Int = 1

scala> x = 2
<console>:13: error: reassignment to val
       x = 2
         ^

Andererseits wird vardas Schlüsselwort verwendet, um eine veränderliche Variable zu deklarieren, dh ihr Wert kann geändert werden:

scala> var y = "bar"
y: String = bar

scala> y = "foo"
y: String = foo

Was wäre, wenn wir einen neuen Wert von berechnen wollten, indem wir yan seinen aktuellen Wert anhängen?

scala> y = y + "bar"
y: String = foobar

Sicher, das funktioniert, aber es stellt sich heraus, dass es dafür eine Abkürzung gibt:

scala> y += "bar"

scala> y
res10: String = foobar

Übrigens ist in Scala +nur der Name einer Methode, also y + "bar"dasselbe wie y.+("bar"). Hässlich, aber gültig. Ebenso y.+=("bar")ist auch ein gültiger Ersatz für y += "bar".

Großartig, merken wir uns das für später. Next ist, wie andere bereits betont haben, ::nur eine Methode , um einer Liste Elemente voranzustellen (von Java aus kann sie als aufgerufen werden someList.$colon$colon(someElement)). Wichtig ist, dass die ::Methode eine neue Liste zurückgibt :

scala> var letters = List("b", "c")
letters: List[String] = List(b, c)

scala> letters.::("a")
res1: List[String] = List(a, b, c)

scala> letters
res2: List[String] = List(b, c)

Was wäre, wenn wir auf die Liste setzen wollten, lettersdie den Buchstaben “a” enthält?

scala> letters = letters.::("a")
letters: List[String] = List(a, b, c)

Beachten Sie, dass dies dem vorherigen Beispiel mit Zeichenfolgen sehr ähnlich sieht. Funktioniert die Kurzschrift auch hier?

scala> letters ::= "a"

scala> letters
res6: List[String] = List(a, b, c)

Ja tut es. letters.::=("a")funktioniert auch.


Lassen Sie uns nun das ursprüngliche Snippet aufschlüsseln:

Schritt 1

Erstellen Sie eine Variable mit dem Namen resund weisen Sie ihr eine leere, unveränderliche Liste zu. Diese leere Liste soll Paare von ganzen Zahlen enthalten (Int, Int).

var res = List[(Int, Int)]()

Hier ist eine alternative Möglichkeit, dasselbe zu tun:

var res = List.empty[(Int, Int)]

(was meiner Meinung nach etwas einfacher zu lesen ist)


Schritt 2

(1, 2)Stellen Sie der Liste ein neues Element voran und weisen Sie resdie resultierende Liste wieder der zu res.

res .::= (1, 2)

Oder ohne Leerzeichen:

res.::=(1, 2)

Kommt mir bekannt vor? Wir hätten es auch so schreiben können:

res = res.::(1, 2)

Schritt 3

Folgen Sie (3, 4)der Logik in Schritt 2


Schritt 4

Drucken Sie den aktuellen Wert von aus res, der sein sollte:List((3,4), (1,2))


Randnotiz

Verwirrenderweise ist der Compiler nachsichtig genug, um uns zu erlauben, beim Aufrufen nur einen einzigen Satz Klammern anzugeben ::, obwohl wir eigentlich zwei Sätze haben sollten: einen für den Methodenaufruf und einen anderen für die Angabe eines Paares von Ganzzahlen. Es gibt also noch eine andere gültige Art, dasselbe zu schreiben res.::=((1, 2)).

Allgemeiner:

scala> def first(p:(Int, Int)):Int = p._1
first: (p: (Int, Int))Int

scala> first(6,7)
res0: Int = 6

scala> first((6,7))
res1: Int = 6

scala> first(6 -> 7) //lolz! another one using implicit conversion
res2: Int = 6

Die implizite Konvertierung ist allgegenwärtig, da sie in Predef definiert ist. ArrowAssoc

Geist = geblasen

Ich empfehle auch einen Blick auf Was sind alle Instanzen von syntaktischem Zucker in Scala?


Beantwortet von –
Andrej


Antwort geprüft von –
Jay B. (FixError Admin)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like