Viele Sprachen wählen die Methode, mit der die Zuweisung zu einer Anweisung und nicht zu einem Ausdruck gemacht wird, einschließlich Python:
foo = 42 # works
if foo = 42: print "hi" # dies
bar(foo = 42) # keyword arg
und Golang:
var foo int
foo = 42 # works
if foo = 42 { fmt.Printn("hi") } # dies
Andere Sprachen haben keine Zuordnung, sondern Gültigkeitsbereichsbindungen, z. B. OCaml:
let foo = 42 in
if foo = 42 then
print_string "hi"
Ist let
jedoch ein Ausdruck an sich.
Das Zulassen der Zuweisung hat den Vorteil, dass wir den Rückgabewert einer Funktion innerhalb der Bedingung direkt überprüfen können, z. B. in diesem Perl-Snippet:
if (my $result = some_computation()) {
say "We succeeded, and the result is $result";
}
else {
warn "Failed with $result";
}
Perl überprüft die Deklaration zusätzlich nur auf diese Bedingung, was sie sehr nützlich macht. Es warnt auch, wenn Sie innerhalb einer Bedingung zuweisen, ohne dort eine neue Variable zu deklarieren - if ($foo = $bar)
wird warnen, if (my $foo = $bar)
wird nicht.
Die Zuordnung in einer anderen Anweisung ist in der Regel ausreichend, kann jedoch zu Problemen beim Scoping führen:
my $result = some_computation()
if ($result) {
say "We succeeded, and the result is $result";
}
else {
warn "Failed with $result";
}
# $result is still visible here - eek!
Golang verlässt sich stark auf Rückgabewerte für die Fehlerprüfung. Es erlaubt daher einer Bedingung, eine Initialisierungsanweisung zu treffen:
if result, err := some_computation(); err != nil {
fmt.Printf("Failed with %d", result)
}
fmt.Printf("We succeeded, and the result is %d\n", result)
Andere Sprachen verwenden ein Typsystem, um nicht-boolesche Ausdrücke in einer Bedingung zu verbieten:
int foo;
if (foo = bar()) // Java does not like this
Dies schlägt natürlich fehl, wenn eine Funktion verwendet wird, die einen Booleschen Wert zurückgibt.
Wir haben jetzt verschiedene Mechanismen gesehen, um uns gegen unbeabsichtigte Zuweisungen zu verteidigen:
- Zuweisung als Ausdruck nicht zulassen
- Verwenden Sie die statische Typprüfung
- Zuordnung existiert nicht, wir haben nur
let
Bindungen
- Erlaube eine Initialisierungsanweisung, lass die Zuordnung sonst nicht zu
- Zuweisung innerhalb einer Bedingung ohne Deklaration nicht zulassen
Ich habe sie nach aufsteigenden Präferenzen geordnet - Zuweisungen in Ausdrücken können nützlich sein (und es ist einfach, Pythons Probleme zu umgehen, indem Sie eine explizite Deklarationssyntax und eine andere benannte Argument-Syntax verwenden). Aber es ist in Ordnung, sie zu verbieten, da es viele andere Optionen gibt, die den gleichen Effekt haben.
Fehlerfreier Code ist wichtiger als knapper Code.