En varios lenguajes (Java al menos, piense también C #?) Puede hacer cosas como
if( condition )
singleStatement;
while( condition )
singleStatement;
for( var; condition; increment )
singleStatement;
Entonces, cuando tengo solo una declaración, no necesito agregar un nuevo alcance con { }
. ¿Por qué no puedo hacer esto con try-catch?
try
singleStatement;
catch(Exception e)
singleStatement;
¿Hay algo especial en try-catch que requiera tener siempre un nuevo alcance o algo así? Y si es así, ¿no podría el compilador arreglar eso?
for
las partes debe llamarse algo asíinitial
,condition
ystep
comoinitial
no necesita definir una variable ystep
no necesita ser un incremento.if
es siempre una declaración única, y las declaraciones múltiples encerradas entre llaves comprenden una declaración única. Pero soy uno de los que siempre ponen los frenos de todos modos, así que ...throw
yreturn
, y como dijo @detly, si consideras las llaves como un solo grupo de declaraciones, no lo encuentro inconsistente tampoco. Nunca he entendido cuáles son estos "muchos errores de codificación" mencionados por la gente. Las personas deben comenzar a prestar atención a lo que hacen, usar la sangría adecuada y hacerse pruebas de unidad: P nunca tuvo un problema con esto ...Respuestas:
En mi opinión, están incluidos en Java y C # principalmente porque ya existían en C ++. La verdadera pregunta, entonces, es por qué C ++ es así. De acuerdo con el diseño y la evolución de C ++ (§16.3):
Editar: En cuanto a por qué esto sería confuso, creo que uno solo tiene que mirar las afirmaciones incorrectas en la respuesta de @Tom Jeffery (y, especialmente, el número de votos positivos que ha recibido) para darse cuenta de que habría un problema. Para el analizador, esto realmente no es diferente de hacer coincidir
else
s conif
llaves que carecen de s para forzar otra agrupación, todas lascatch
cláusulas coincidirían con las más recientesthrow
. Para aquellos lenguajes erróneos que lo incluyen, lasfinally
cláusulas harían lo mismo. Desde el punto de vista del analizador, esto no es lo suficientemente diferente de la situación actual como para darse cuenta, en particular, como están las gramáticas ahora, realmente no hay nada para agrupar lascatch
cláusulas; los corchetes agrupan las declaraciones controladas por elcatch
cláusulas, no las cláusulas de captura en sí.Desde el punto de vista de escribir un analizador sintáctico, la diferencia es casi demasiado pequeña para notarla. Si comenzamos con algo como esto:
Entonces la diferencia sería entre:
y:
Del mismo modo, para las cláusulas catch:
vs.
Sin embargo, la definición de un bloque try / catch completo no necesitaría cambiar en absoluto. De cualquier manera, sería algo como:
[Aquí estoy usando
[whatever]
para indicar algo opcional, y estoy dejando de lado la sintaxis para un,finally_clause
ya que no creo que tenga ninguna relación con la pregunta.]Incluso si no intenta seguir toda la definición de gramática similar a Yacc allí, el punto puede resumirse con bastante facilidad: esa última declaración (comenzando con
try_block
) es aquella en la que lascatch
cláusulas se combinan con lastry
cláusulas, y sigue siendo exactamente el igual si se requieren o no las llaves.Para reiterar / resumir: las llaves agrupan las declaraciones controladas por la
catch
s, pero no agrupan lascatch
s mismas. Como tal, esos aparatos no tienen absolutamente ningún efecto al decidir cuálcatch
va con quétry
. Para el analizador / compilador, la tarea es igualmente fácil (o difícil) de cualquier manera. A pesar de esto, la respuesta de Tom @ (y el número de up-votos que ha recibido) proporciona amplia demostración del hecho de que un tal cambio haría con los usuarios es casi seguro que confundirlo.fuente
try return g(); catch(xxii) error("G() goofed: xxii");
debería haber sido ordenado todavía IMOEn una respuesta sobre por qué se requieren corchetes para algunas construcciones de una sola declaración pero no para otras , Eric Lippert escribió:
En otras palabras, era más costoso para el equipo compilador implementarlo de lo que estaba justificado, por el beneficio marginal que proporcionaría.
fuente
Creo que es para evitar colgar otros problemas de estilo. Lo siguiente sería ambiguo ...
Podría significar esto:
O...
fuente
if
caso. Es fácil decir "bueno, si no, se une al más profundo si" y terminar con eso. Pero para try / catch eso no funciona.Creo que la razón principal es que hay muy poco que pueda hacer en C # que necesite un bloque try / catch que sea solo una línea. (No puedo pensar en ninguna en este momento en la parte superior de mi cabeza). Puede tener un punto válido en términos del bloque catch, por ejemplo, una instrucción de una línea para registrar algo, pero en términos de legibilidad tiene más sentido (al menos para mí) requerir {}.
fuente