2016-06-28 8 views
2

Ich spiele herum mit JSON Spiel Bibliothek vor kurzem, und bemerkte, dass dies nicht kompilieren:Scala: Zwei von Doppelpunkt Unterstrichen analysiert als ein Token

val steps = Seq("a", "b", "c") 
steps.foldLeft(__)((a, x) => a \ x) 

Nach einem wenig Bastelei und die Quelle gerade, ich den richtigen Ausdruck gefunden:

steps.foldLeft(JsPath())((a, x) => a \ x) 

oder sogar:

steps.foldLeft(__())((a, x) => a \ x) 

... obwohl die zweite man sieht ziemlich verschleiert aus.

Später fand ich eine effizientere und prägnanten Ausdruck:

JsPath(steps.toList map KeyPathNode) 

Aber ich behielt auf den ursprünglichen Ausdruck auf Rückkehr und spielen mit ihm um. Ich fand, dass dies funktioniert:

steps.foldLeft(JsPath: JsPath)((a, x) => a \ x) 

Irgendwie dies nicht:

steps.foldLeft(__: JsPath)((a, x) => a \ x) 

ich error: not found: value __. Dies funktioniert jedoch:

steps.foldLeft((__): JsPath)((a, x) => a \ x) 

Dies funktioniert auch:

steps.foldLeft({__}: JsPath)((a, x) => a \ x) 

Auch dies:

steps.foldLeft(__.asInstanceOf[JsPath])((a, x) => a \ x) 

Warum ist es, dass der Ausdruck mit __: JsPath ausfällt?

... Aaaaaand kurz bevor ich im Begriff war, diese Frage zu unterbreiten ich einen anderen Arbeits Ausdruck gefunden:

steps.foldLeft(__ : JsPath)((a, x) => a \ x) 

Es scheint, der Parser __: als ein Token interpretiert. Aber warum sollte es das tun? Ich dachte, Unterstreichung ist nur ein anderes gültiges Identifizierungszeichen. Gibt es eine spezielle Parsing-Regel, die verantwortlich ist?

Antwort

3

Underscore ist speziell in Bezeichnern genau, weil es von Operatorzeichen gefolgt werden kann, einschließlich :: z. foo_+ ist ein Bezeichner, wobei foo+ zwei Tokens ist: foo+.

First, an identifier can start with a letter which can be followed by an arbitrary sequence of letters and digits. This may be followed by underscore _ characters and another string composed of either letters and digits or of operator characters.

Beachten Sie, dass _ und $ hier Großbuchstaben für die Zwecke des ersten Satzes berücksichtigt werden. Also __: ist eine rechtliche Kennung, aber _: ist nicht.

+1

Nicht erlaubt, im Kommentar zu verbessern, aber klickbares Zitat ist sehr praktisch. Nur um info hinzuzufügen: Unterstrich ist Kleinschreibung für Muster varid: '42 match {case __: => __:}'. Jetzt brauchen wir einen Anwendungsfall. Ich habe einmal versucht, erweiterte Unterstreichung für das Ausrichten von Case-Pfeilen, aber jetzt werde ich versuchen, '42 match {case __ ========> =>()}' –

+0

Das ist neugierig. Ich habe dies unter https://groups.google gefragt.com/forum/#! topic/scala-user/sh20Vr2BK9Y. –