In verschiedenen Sprachen (Java zumindest, denken Sie auch C #?) Können Sie Dinge wie
if( condition )
singleStatement;
while( condition )
singleStatement;
for( var; condition; increment )
singleStatement;
Wenn ich also nur eine Anweisung habe, muss ich keinen neuen Bereich hinzufügen { }
. Warum kann ich das nicht mit try-catch machen?
try
singleStatement;
catch(Exception e)
singleStatement;
Gibt es etwas Besonderes an Try-Catch, das immer einen neuen Umfang erfordert oder so? Und wenn ja, konnte der Compiler das nicht beheben?
for
die Teile so etwas heißeninitial
,condition
undstep
dainitial
muss keine Variable definiert undstep
kein Inkrement sein.if
immer eine einzelne Anweisung ist und mehrere in geschweifte Klammern gesetzte Anweisungen eine einzelne Anweisung umfassen. Aber ich bin einer von denen, die sowieso immer die Zahnspange tragen, also ...throw
undreturn
, und wie @detly sagte, wenn Sie die geschweiften Klammern als eine einzelne Gruppe von Anweisungen betrachten, finde ich es nicht inkonsistent entweder. Ich habe nie verstanden, was diese "vielen Codierungsfehler" sind, von denen die Leute sprechen. Die Leute müssen anfangen, auf das zu achten, was sie tun, die richtigen Einrückungen anwenden und Unit-Tests durchführen: P hatte nie ein Problem damit ...Antworten:
IMO, sie sind hauptsächlich in Java und C # enthalten, weil sie bereits in C ++ existierten. Die eigentliche Frage ist also, warum C ++ so ist. Nach dem Entwurf und der Entwicklung von C ++ (§16.3):
Edit: Was den Grund für die Verwirrung angeht, muss man meiner Meinung nach nur die falschen Behauptungen in @Tom Jefferys Antwort (und insbesondere die Anzahl der erhaltenen Up-Votes) betrachten, um zu erkennen, dass es ein Problem geben würde. Für den Parser ist dies nicht anders als das Abgleichen von
else
s mitif
s - ohne geschweifte Klammern, um eine andere Gruppierung zu erzwingen, würden allecatch
Klauseln mit den neuesten übereinstimmenthrow
. Für jene missverstandenen Sprachen, die es enthalten,finally
würden Klauseln dasselbe tun. Aus Sicht des Parsers unterscheidet sich dies kaum genug von der aktuellen Situation, um zu bemerken - insbesondere gibt es nach heutigem Stand der Grammatik nichts, um diecatch
Klauseln zu gruppieren - die Klammern gruppieren die Anweisungen, die von der gesteuert werdencatch
Klauseln, nicht die catch-Klauseln selbst.Aus der Sicht, einen Parser zu schreiben, ist der Unterschied fast zu gering, um es zu bemerken. Wenn wir mit so etwas beginnen:
Dann wäre der Unterschied zwischen:
und:
Ebenso für catch-Klauseln:
gegen
Die Definition eines vollständigen Try / Catch-Blocks müsste sich jedoch nicht ändern. In jedem Fall wäre es so etwas wie:
[Hier gebe ich
[whatever]
etwas Optionales an und lasse die Syntax für a aus,finally_clause
da ich glaube, dass sie keinen Einfluss auf die Frage hat.]Auch wenn Sie dort nicht versuchen, alle Yacc-ähnlichen Grammatikdefinitionen zu befolgen, lässt sich der Punkt ziemlich einfach zusammenfassen: Diese letzte Anweisung (beginnend mit
try_block
) ist diejenige, bei dercatch
Klauseln mittry
Klauseln abgeglichen werden - und sie bleibt genau die gleich, ob die Klammern erforderlich sind oder nicht.Um es zu wiederholen / Fassen wir zusammen: die Klammern Gruppe zusammen die gesteuerten Aussagen durch die
catch
s, aber nicht Gruppe dercatch
s selbst. Als solche haben diese Klammern absolut keinen Einfluss auf die Entscheidung , welchecatch
mit dem gehttry
. Für den Parser / Compiler ist die Aufgabe in beiden Fällen gleichermaßen einfach (oder schwierig). Trotzdem zeigt die Antwort von @ Tom (und die Anzahl der abgegebenen Stimmen), dass eine solche Änderung die Benutzer mit ziemlicher Sicherheit verwirren würde .quelle
try return g(); catch(xxii) error("G() goofed: xxii");
Wäre noch ordentlich gewesen IMOIn einer Antwort darauf, warum für einige Konstrukte mit nur einer Anweisung Klammern erforderlich sind, andere jedoch nicht , schrieb Eric Lippert:
Mit anderen Worten, es war für das Compilerteam teurer, es zu implementieren, als es gerechtfertigt war, und dies zu dem Grenznutzen, den es bieten würde.
quelle
Ich denke, es ist zu vermeiden, andere Stilprobleme baumeln zu lassen. Folgendes wäre mehrdeutig ...
Das könnte bedeuten:
Oder...
quelle
if
Fall nicht mehrere mögliche Dangling else-Klauseln gibt . Es ist einfach zu sagen "Nun, das Andere bindet an das Innerste, wenn" und damit fertig zu sein. Aber für try / catch funktioniert das nicht.Ich denke, der Hauptgrund ist, dass es in C # sehr wenig gibt, das einen Try / Catch-Block benötigt, der nur aus einer Zeile besteht. (Ich kann mir im Moment keine vorstellen). Sie können einen gültigen Punkt in Bezug auf den catch-Block haben, z. B. eine einzeilige Anweisung, um etwas zu protokollieren, aber in Bezug auf die Lesbarkeit ist es (zumindest für mich) sinnvoller, {} zu fordern.
quelle