IMO, są zawarte w Javie i C # głównie dlatego, że już istniały w C ++. Prawdziwe pytanie brzmi zatem, dlaczego C ++ jest w ten sposób. Zgodnie z projektem i ewolucją C ++ (§ 16.3):
Słowo trykluczowe jest całkowicie zbędne, podobnie jak { }nawiasy klamrowe, chyba że w instrukcji try-block lub module obsługi znajduje się wiele instrukcji. Na przykład zezwolenie na:
int f()
{
return g() catch(xxii) { // not C++
error("G() goofed: xxii");
return 22;
};
}
Jednak tak trudno mi było wytłumaczyć, że wprowadzono nadmiarowość, aby uratować personel pomocniczy przed zdezorientowanymi użytkownikami.
Edycja: Jeśli chodzi o to, dlaczego byłoby to mylące, myślę, że wystarczy spojrzeć na niepoprawne twierdzenia w odpowiedzi @ Toma Jeffery'ego (a zwłaszcza na liczbę głosów, jakie otrzymało), aby zdać sobie sprawę, że będzie problem. Dla parsera tak naprawdę nie różni się to od dopasowania elses do ifs - brak nawiasów klamrowych do wymuszenia innego grupowania, wszystkie catch klauzule pasowałyby do najnowszej throw. W przypadku tych źle wprowadzonych języków, które go zawierają, finallyklauzule zrobiłyby to samo. Z punktu widzenia parsera nie jest to wystarczająco różniące się od obecnej sytuacji, aby zauważyć - w szczególności, ponieważ gramatyka stoi teraz, tak naprawdę nie ma nic do grupowania catchklauzul - nawiasy grupują instrukcje sterowane przezcatch klauzule, a nie same klauzule catch.
Z punktu widzenia pisania parsera różnica jest prawie zbyt mała, aby zauważyć. Jeśli zaczniemy od czegoś takiego:
simple_statement: /* won't try to cover all of this */
;
statement: compound_statement
| simple_statement
;
statements:
| statements statement
;
compound_statement: '{' statements '}'
catch_arg: '(' argument ')'
Wtedy różnica byłaby między:
try_clause: 'try' statement
i:
try_clause: 'try' compound_statement
Podobnie w przypadku klauzul połowowych:
catch_clause: 'catch' catch_arg statement
vs.
catch_clause: 'catch' catch_arg compound_statement
Jednak definicja kompletnego bloku try / catch nie musiałaby się wcale zmieniać. Tak czy inaczej, byłoby to coś takiego:
catch_clauses:
| catch_clauses catch_clause
;
try_block: try_clause catch_clauses [finally_clause]
;
[Tutaj używam [whatever]do wskazania czegoś opcjonalnego i pomijam składnię, finally_clauseponieważ nie sądzę, żeby miało to jakikolwiek związek z pytaniem.]
Nawet jeśli nie starają się przestrzegać wszystkich Yacc-jak tam definicji gramatyki, punkt można podsumować dość łatwo: to ostatnie stwierdzenie (począwszy try_block) to jeden gdzie catchklauzule uzyskać dopasowane z tryklauzul - i pozostaje dokładnie to samo, czy nawiasy klamrowe są wymagane, czy nie.
Powtórzmy / Podsumowując: grupa szelki wraz oświadczenia kontrolowanych przez tych catchs, ale czy nie Group catchs sami. Jako takie, nawiasy klamrowe nie mają absolutnie żadnego wpływu na decyzję, która catchz nich idzie try. Dla parsera / kompilatora zadanie jest równie łatwe (lub trudne) w obu kierunkach. Pomimo tego, @ Toma odpowiedzi (oraz liczby głosów up-to odebrane) zapewnia wystarczającą demonstrację faktu, że taka zmiana would prawie na pewno błąd użytkowników.
forczęści należy nazwać coś w rodzajuinitial,conditionistepponieważinitialnie musi definiować zmiennej istepnie musi być przyrostem.