Багато мов вибирають шлях складання заяви, а не виразу, включаючи Python:
foo = 42 # works
if foo = 42: print "hi" # dies
bar(foo = 42) # keyword arg
і Голанг:
var foo int
foo = 42 # works
if foo = 42 { fmt.Printn("hi") } # dies
Інші мови не мають призначення, а скоріше прив'язки, наприклад, OCaml:
let foo = 42 in
if foo = 42 then
print_string "hi"
Однак, let
це сам вираз.
Перевага дозволу на призначення полягає в тому, що ми можемо безпосередньо перевірити повернене значення функції всередині умовного, наприклад, у цьому фрагменті Perl:
if (my $result = some_computation()) {
say "We succeeded, and the result is $result";
}
else {
warn "Failed with $result";
}
Perl додатково привласнює декларацію лише до тієї умовної, що робить її дуже корисною. Він також попередить, якщо призначити всередині умовного, не оголошуючи там нову змінну - if ($foo = $bar)
попередить, if (my $foo = $bar)
не буде.
Здійснення призначення в іншому операторі, як правило, достатньо, але може спричинити проблеми з визначенням:
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 сильно покладається на значення повернення для перевірки помилок. Тому це дозволяє умовно приймати оператор ініціалізації:
if result, err := some_computation(); err != nil {
fmt.Printf("Failed with %d", result)
}
fmt.Printf("We succeeded, and the result is %d\n", result)
Інші мови використовують систему типів, щоб заборонити небулеві вирази всередині умовного:
int foo;
if (foo = bar()) // Java does not like this
Звичайно, це не вдається при використанні функції, яка повертає булеву форму.
Зараз ми побачили різні механізми захисту від випадкового призначення:
- Заборонити призначення як вираз
- Використовуйте статичну перевірку типу
- Призначення не існує, у нас є лише
let
прив’язки
- Дозволити оператор ініціалізації, заборонити призначення інакше
- Заборонити призначення всередині умовного без декларації
Я класифікував їх за уподобанням переваг - призначення всередині виразів може бути корисним (і просто обійти проблеми Python, маючи явний синтаксис декларації та інший синтаксис аргументу з назвою). Але нормально їх заборонити, оскільки існує багато інших варіантів того ж ефекту.
Код без помилок важливіший за короткий код.