10 Stimmen

Scala Mehrfachzuweisung an bestehende Variable

Ich kann etwas tun wie

def f(): Tuple2[String, Long] = ...
val (a, b) = f()

Was ist, wenn die Variablen bereits vorhanden sind? Ich lasse die gleichen Datensätze über Filter laufen und möchte sie nicht verketten (lange Namen und so). Das habe ich versucht, aber es beschwert sich über die Erwartung von ; anstelle von = in der letzten Zeile:

var a = ...initialization for this data
var b = ...some other init
(a, b) = g(a, b) // error: expected ';' but found '='

Gibt es eine Möglichkeit, ein Zwischentupel zu vermeiden?

14voto

Tom Crockett Punkte 29618

Wie Alex schon sagte, lautet die kurze Antwort: Nein. Was in Ihrem Code vor sich geht, ist Folgendes: Wenn a y b sind bereits gebundene Variablen im aktuellen Bereich, (a, b) bedeutet "nimm die Werte von a und b und bilde daraus ein Tupel".

Deshalb,

(a, b) = ...

ist gleichbedeutend mit

(new Tuple2(a, b)) = ...

was offensichtlich nicht das ist, was Sie wollen (abgesehen davon, dass es unsinnig ist).

Die von Ihnen gewünschte Syntax (die Möglichkeit, mehreren Variablen gleichzeitig zuzuweisen) gibt es einfach nicht. Sie können nicht einmal die gleicher Wert auf mehrere bereits existierende Variablen gleichzeitig anwenden (die übliche Syntax "a = b = ...", die in vielen anderen Sprachen zu finden ist, funktioniert in Scala nicht). Ich glaube nicht, dass es ein Zufall ist, dass vals gegenüber vars bevorzugt behandelt werden; sie sind fast immer eine bessere Idee.

Es hört sich so an, als ob all dies innerhalb einer Art Schleife stattfindet und wiederholte Zuweisungen durchgeführt werden. Dies ist nicht sehr idiomatisch Scala. Ich würde empfehlen, dass Sie versuchen, die Verwendung von Vars in Ihrem Programm zu beseitigen und die Dinge in einer funktionalen Weise zu tun, unter Verwendung der wie map, flatMap, Filter, foldLeft, etc.

9voto

Alex Cruise Punkte 7779

Kurze Antwort: Nein.

1voto

Daniel C. Sobral Punkte 290004

Sie funktioniert für neue Werte, da diese Syntax wie ein Mustervergleich behandelt wird, genau wie Case-Anweisungen. Also, als Alex sagte, Sie können es nicht tun.

0voto

Landei Punkte 53286

Wenn Sie immer "dieselben Datensätze" über Filter usw. laufen lassen, ist das ein Symptom dafür, dass sie irgendwie zusammengehören, so dass Sie in Erwägung ziehen sollten, sie entweder mit einem Tupel oder einer speziellen Klasse zu gruppieren (in solchen Fällen in der Regel eine Fallklasse).

0voto

Sujee Maniyam Punkte 1083

Die von mir gefundene Lösung ist folgende:

// declare as var, not val
var x = (1,"hello")  
// x: (Int, String) = (1,hello)

// to access first element
x._1
// res0: Int = 1

// second element
x._2
// res1: String = hello

// now I can re-assign x to something else
x = (2, "world")
// x: (Int, String) = (2,world)

// I can only re-assign into x as long the types match
// the following will fail

x = (3.14, "Hmm Pie")
<console>:8: error: type mismatch;
 found   : Double(3.14)
 required: Int
       x = (3.14, "Hmm Pie")

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X