ИМО, они включены в 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:
catch_clause: 'catch' catch_arg statement
против
catch_clause: 'catch' catch_arg compound_statement
Хотя определение полного блока try / catch не нужно менять вообще. В любом случае это будет что-то вроде:
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
не должно быть приращения.