2016-04-02 7 views
3

Nehmen wir an, die Funktion r gibt das Tupel von fünf Werten zurück.Scala Bug oder Funktion? Mehrfachzuordnungsfehler mit Großbuchstabenvariablen

scala> def r = (1,2,3,4,5) 
r: (Int, Int, Int, Int, Int) 

Als ich den zurückgegebenen Wert von r zuweisen, bekam ich Fehler mit Schreiben veränderlichem Kapital.

scala> val (a,b,c,d,E) = r 
<console>:13: error: not found: value E 
     val (a,b,c,d,E) = r 
        ^

Wenn ich den Großbuchstaben nicht verwende, tritt kein Fehler auf.

scala> val (a,b,c,d,e) = r 
a: Int = 1 
b: Int = 2 
c: Int = 3 
d: Int = 4 
e: Int = 5 

Allerdings kann ich Großbuchstaben Variable mit einzelnen assignemnt zuweisen.

scala> val Q = 10 
Q: Int = 10 

Ist dies ein Fehler oder eine Funktion von Scala?

Antwort

5

Es ist eine Funktion ... wenn auch nicht sehr wünschenswert.

Wenn Sie val (a,b,c) = tuple tun, es ist eigentlich ein Mustervergleich:

tuple match { 
    case (a,b,c) => ... 
} 

Nun, diese Aussage oben extrahiert drei Werte von Tupel unapply verwenden, und ordnet sie a, b und c. Aber das:

tuple match { 
    case (1, 2, 3) => ... 
} 

Tut etwas anderes. Es extrahiert die drei Werte aus dem Tupel und vergleicht sie mit den drei Werten auf der linken Seite. Was passiert, wenn Sie wollten gegen eine Variable zum Spiel:

val foo = 1 
val bar = 2 
val bat = 3 

tuple match { 
    case(foo, bar, bat) => ... 
} 

Das wird nicht funktionieren: Dieser Fall ist genau die gleiche wie die erste, und tun genau das Gleiche: es werden die Werte aus dem Tupel extrahieren in drei (neue) lokale Variablen ohne Übereinstimmung. Was aber, wenn Sie die Variablen anpassen wollten? Wie komme ich damit klar? Es gibt zwei Möglichkeiten: Sie können die Variablennamen in Backticks einschließen kann oder Sie machen die Namen mit einem captial Buchstaben beginnen:

val Foo = 1 
    val bar = 2 
    var baz = 3 

    tuple match { 
    case(Foo, `bar`, `bat`) => ... 
    } 

zusammenfassen zu: tuple match { case (foo, _) => bedeutet „aus Tupel das erste Element extrahieren und weisen auf eine neue Variable footuple match { case (Foo, _) bedeutet "führe diese case aus, wenn das erste Element des Tupels gleich dem Wert einer existierenden Variablen Foo ist." "Zuweisungen" folgen der gleichen Logik (weil sie nicht wirklich "Zuweisungen" sind, sondern nur eine andere) Syntax für die Musterübereinstimmung), also wenn Sie val (a,b,c,d,E) = r sagen, bedeutet dies "weisen Sie die ersten vier Elemente vonzuan die neuen Variablen und passen Sie das letzte Element an die vorhandene Variable an E ". Aber E existiert nicht, also der Fehler.

+0

Gibt es eine Möglichkeit, dies zu umgehen und zu tun, was OP tun möchte, indem Sie den Wert einer Variablen zuweisen, die mit einem Großbuchstaben beginnt? Wie das Gegenteil von Backticks? –

+0

@LuigiPlinge nicht, dass ich weiß ... anders als etwas wie 'val (a, b) = Tupel; val B = b ' – Dima

2

Es heißt Stable Identifiers. Wenn Sie also einen Großbuchstaben als Variablennamen (oder am Anfang eines Variablennamens) verwenden, während Sie eine Musterübereinstimmung machen (was in diesem Fall der Fall ist), denkt der Compiler, dass dies ein konstanter Wert ist und geht damit zum Verhalten (Vergleich der beiden Werte E und 5 anstelle der Zuordnung von 5 zu E).

Beispiele:

val (a,b,c,d,extsom) = r Dies funktioniert.

val (a,b,c,d,Extsom) = r Dies wird nicht.

Verwandte Themen