W różnych językach (przynajmniej Java, myślisz również C #?) Możesz robić takie rzeczy
if( condition )
singleStatement;
while( condition )
singleStatement;
for( var; condition; increment )
singleStatement;
Więc kiedy mam tylko jedną instrukcję, nie muszę dodawać nowego zakresu { }
. Dlaczego nie mogę tego zrobić za pomocą try-catch?
try
singleStatement;
catch(Exception e)
singleStatement;
Czy jest coś specjalnego w try-catch, która zawsze wymaga posiadania nowego zakresu lub czegoś takiego? A jeśli tak, to czy kompilator nie może tego naprawić?
for
części należy nazwać coś w rodzajuinitial
,condition
istep
ponieważinitial
nie musi definiować zmiennej istep
nie musi być przyrostem.if
jest zawsze pojedynczą instrukcją, a wiele instrukcji zawartych w nawiasach klamrowych zawiera jedną instrukcję. Ale i tak jestem jednym z tych, którzy zawszethrow
ireturn
, jak powiedziałem @detly, jeśli uznasz nawiasy klamrowe za jedną grupę instrukcji, nie znajdę go niekonsekwentne. Nigdy nie zrozumiałem, jakie są te „masowe błędy kodowania”, o których wspominają ludzie. Ludzie muszą zacząć zwracać uwagę na to, co robią, stosować odpowiednie wcięcie i przeprowadzać testy jednostkowe: P nigdy nie miał z tym problemu ...Odpowiedzi:
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):
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 doif
s - brak nawiasów klamrowych do wymuszenia innego grupowania, wszystkiecatch
klauzule pasowałyby do najnowszejthrow
. 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 grupowaniacatch
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:
Wtedy różnica byłaby między:
i:
Podobnie w przypadku klauzul połowowych:
vs.
Jednak definicja kompletnego bloku try / catch nie musiałaby się wcale zmieniać. Tak czy inaczej, byłoby to coś takiego:
[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 gdziecatch
klauzule uzyskać dopasowane ztry
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 Groupcatch
s sami. Jako takie, nawiasy klamrowe nie mają absolutnie żadnego wpływu na decyzję, któracatch
z nich idzietry
. 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.źródło
try return g(); catch(xxii) error("G() goofed: xxii");
mogłoby być jeszcze fajnie IMOW odpowiedzi na pytanie, dlaczego w niektórych konstrukcjach z pojedynczą instrukcją są wymagane nawiasy klamrowe , Eric Lippert napisał:
Innymi słowy, wdrożenie go przez zespół kompilatora kosztowało więcej niż było to uzasadnione, ze względu na marginalną korzyść.
źródło
Myślę, że ma to na celu uniknięcie problemów związanych ze stylem. Poniższe byłyby dwuznaczne ...
Może to oznaczać:
Lub...
źródło
if
sprawy. Łatwo jest po prostu powiedzieć „cóż, reszta wiąże się z najbardziej wewnętrznym, jeśli” i zrobić to. Ale dla try / catch to nie działa.Myślę, że głównym powodem jest to, że niewiele można zrobić w języku C #, który wymagałby bloku try / catch, który jest tylko jedną linią. (Nie mogę teraz wymyślić żadnego z głowy). Możesz mieć ważny punkt pod względem bloku catch, np. Instrukcja jednowierszowa, aby coś zarejestrować, ale pod względem czytelności bardziej sensowne (przynajmniej dla mnie) jest wymaganie {}.
źródło