IMO, вони включені в Java та C # насамперед тому, що вони вже існували в C ++. Справжнє питання, чому це C ++ саме так. Відповідно до проектування та еволюції C ++ (§16.3):
try
Ключове слово повністю надмірне і тому є { }
дужками , за винятком , коли кілька операторів насправді використовується в примірках блоку або обробник. Наприклад, було б тривіально дозволити:
int f()
{
return g() catch(xxii) { // not C++
error("G() goofed: xxii");
return 22;
};
}
Однак мені це було важко пояснити тим, що резервування було введено, щоб врятувати допоміжний персонал від розгублених користувачів.
Редагувати: Щодо того, що це буде заплутано, я думаю, що слід лише подивитися на неправильні твердження у відповіді @Tom Jeffery (і, особливо, кількість отриманих голосів), щоб зрозуміти, що це буде проблема. На думку аналізатора, це насправді нічим не відрізняється від збігу else
s з if
s - бракує дужок, щоб змусити інше групування, всі catch
пропозиції відповідатимуть останнім throw
. Для тих неправильних мовних текстів, які включають його, finally
пункти будуть робити те саме. З точки зору аналізатора, це навряд чи достатньо відрізняється від нинішньої ситуації, щоб помітити - зокрема, коли граматики стоять зараз, насправді нічого не можна згрупувати, catch
- дужки групують заяви, контрольованіcatch
пункти, а не самі застереження.
З точки зору написання аналізатора, різниця майже занадто крихітна, щоб помітити. Якщо ми почнемо з чогось такого:
simple_statement: /* won't try to cover all of this */
;
statement: compound_statement
| simple_statement
;
statements:
| statements statement
;
compound_statement: '{' statements '}'
catch_arg: '(' argument ')'
Тоді різниця буде між:
try_clause: 'try' statement
і:
try_clause: 'try' compound_statement
Точно так само і щодо статей про улов:
catch_clause: 'catch' catch_arg statement
vs.
catch_clause: 'catch' catch_arg compound_statement
Визначення повного блоку спробу / лову взагалі не потрібно змінювати. У будь-якому випадку це буде щось на кшталт:
catch_clauses:
| catch_clauses catch_clause
;
try_block: try_clause catch_clauses [finally_clause]
;
[Тут я використовую [whatever]
для позначення чогось необов’язкового, і я покидаю синтаксис, finally_clause
оскільки не думаю, що це має відношення до питання.]
Навіть якщо ви не намагаєтеся дотримуватись усіх тамтешніх граматичних визначень, які викладені у Yacc, то пункт можна досить легко підсумувати: це останнє твердження (починаючи з try_block
) - це те, де catch
пропозиції узгоджуються з try
пунктами - і це залишається саме тим те саме, потрібні брекети чи ні.
Повторимо / Підіб'ємо підсумок: дужки група разом оператори , контрольовані з допомогою тих catch
х, але робити НЕ групувати catch
самі с. Як такі, такі брекети абсолютно не впливають на вирішення того, з чим catch
йде try
. Для аналізатора / компілятора завдання є однаково легким (або складним) у будь-якому випадку. Незважаючи на це, @ відповідь Тома (і кількість підвищують голосів , якими вона отримала) забезпечує достатню демонстрацію того факту , що така зміна б майже напевно заплутати користувач.
for
частин слід називати щось на зразокinitial
,condition
іstep
якinitial
не потрібно визначати змінну іstep
не повинно бути збільшення.