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 try
kluczowe 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 else
s do if
s - 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ą, finally
klauzule 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 catch
klauzul - 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_clause
ponieważ 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 catch
klauzule uzyskać dopasowane z try
klauzul - 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 catch
s, ale czy nie Group catch
s sami. Jako takie, nawiasy klamrowe nie mają absolutnie żadnego wpływu na decyzję, która catch
z 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.
for
części należy nazwać coś w rodzajuinitial
,condition
istep
ponieważinitial
nie musi definiować zmiennej istep
nie musi być przyrostem.