Wiele języków wybiera drogę przypisywania instrukcji zamiast wyrażenia, w tym Python:
foo = 42 # works
if foo = 42: print "hi" # dies
bar(foo = 42) # keyword arg
i Golang:
var foo int
foo = 42 # works
if foo = 42 { fmt.Printn("hi") } # dies
Inne języki nie mają przypisania, ale raczej powiązania o zasięgu, np. OCaml:
let foo = 42 in
if foo = 42 then
print_string "hi"
Jednak let
to samo wyrażenie.
Zaletą zezwolenia na przypisanie jest to, że możemy bezpośrednio sprawdzić wartość zwracaną funkcji w warunku, np. W tym fragmencie Perla:
if (my $result = some_computation()) {
say "We succeeded, and the result is $result";
}
else {
warn "Failed with $result";
}
Perl dodatkowo ogranicza deklarację tylko do tego warunku, co czyni go bardzo przydatnym. Ostrzeże również, jeśli przypiszesz wewnątrz warunku bez zadeklarowania nowej zmiennej - if ($foo = $bar)
ostrzeże, if (my $foo = $bar)
nie zrobi tego.
Wykonanie przypisania w innej instrukcji jest zwykle wystarczające, ale może powodować problemy z określaniem zakresu:
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 w dużym stopniu opiera się na wartościach zwracanych przy sprawdzaniu błędów. W związku z tym umożliwia warunkowe przyjęcie instrukcji inicjalizacji:
if result, err := some_computation(); err != nil {
fmt.Printf("Failed with %d", result)
}
fmt.Printf("We succeeded, and the result is %d\n", result)
Inne języki używają systemu typów, aby nie dopuszczać wyrażeń innych niż boolowskie wewnątrz warunkowego:
int foo;
if (foo = bar()) // Java does not like this
Oczywiście kończy się to niepowodzeniem, gdy używana jest funkcja zwracająca wartość logiczną.
Widzieliśmy teraz różne mechanizmy obrony przed przypadkowym przydzieleniem:
- Nie zezwalaj na przypisanie jako wyrażenie
- Użyj sprawdzania typu statycznego
- Przypisanie nie istnieje, mamy tylko
let
powiązania
- Zezwalaj na instrukcję inicjalizacji, w przeciwnym razie nie zezwalaj na przypisanie
- Nie zezwalaj na przypisywanie wewnątrz warunkowego bez deklaracji
Posortowałem je w kolejności rosnącej preferencji - przydziały w wyrażeniach mogą być przydatne (i łatwo jest ominąć problemy Pythona poprzez jawną składnię deklaracji i inną nazwaną składnię argumentów). Ale można je zabronić, ponieważ istnieje wiele innych opcji tego samego efektu.
Kod wolny od błędów jest ważniejszy niż kod zwięzły.