Por ejemplo, ¿preferirías esta línea única?
int median(int a, int b, int c) {
return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
o una solución if / else que involucra múltiples declaraciones de devolución?
¿Cuándo es ?:
apropiado y cuándo no? ¿Debería enseñarse u ocultarse a los principiantes?
operators
conditions
FredOverflow
fuente
fuente
Respuestas:
No, es una bendición.
Cuando es algo tan simple que no quieres desperdiciar muchas líneas.
Cuando la legibilidad y la claridad del código se resienten y aumenta la posibilidad de un error por falta de atención, por ejemplo, con muchos operadores encadenados, como en su ejemplo.
La prueba de fuego es cuando comienzas a dudar de que tu código sea fácil de leer y mantener a largo plazo. Entonces no lo hagas.
fuente
myVar = someExpression ? false : true;
(someExpression ? var1 : var2)++
:-)Creo que el operador ternario sin verificar (es decir, una declaración donde se usa solo una vez) está bien, pero si anida más de uno, se vuelve algo difícil de leer.
fuente
¿Cuándo es?: Apropiado
y cuando no?
Si tiene alguna llamada lógica o de función dentro de la expresión ternaria, es horrible verla.
fuente
Una diferencia que (creo) que nadie ha señalado es que si no puede devolver un valor, mientras que el operador ternario sí.
Viniendo de F #, a veces me gusta usar el operador ternario para imitar la coincidencia de patrones.
vs
fuente
var res = function() {switch(input) {case 1: return "1"; case 2: return "2"; ...}}()
emular interruptores como expresiones.expression
ystatement
siempre me preocupa que lasconst
variables que no se pueden cambiar más adelante.Un ejemplo (en mi humilde opinión) de un uso válido:
Esto da como resultado un código más legible que tener 2 declaraciones de impresión distintas. Los ejemplos anidados dependen: (¿comprensible? Sí: no)
fuente
Absolutamente no malvado. De hecho, es puro , y si no lo es.
En lenguajes funcionales como Haskell, F #, ML, etc., son las declaraciones if-then-else las que se consideran malvadas.
La razón de esto es que cualquier "acción" como una declaración imperativa if-then-else requiere que separe una declaración de variable de su definición e introduce el estado en su función.
Por ejemplo, en el siguiente código:
vs.
El primero tiene dos ventajas además de ser más corto:
x
es una constante y, por lo tanto, ofrece muchas menos posibilidades de introducir errores, y puede optimizarse de una manera que el segundo nunca podría ser.x
debe ser de tipoParity
.Confusamente, en lenguajes funcionales, el operador ternario a menudo se llama if-then-else. En Haskell, se podría decir
x = if n mod 3 == 1 then Odd else Even
.fuente
Esa expresión particular me duele los ojos; Atacaría a cualquier desarrollador de mi equipo que lo usara porque no se puede mantener.
Los operadores ternarios no son malos cuando se usan bien. Ni siquiera tienen que ser líneas simples; Una larga que esté bien formateada puede ser muy clara y fácil de entender:
Me gusta más que la cadena if / then / else equivalente:
Los reformatearé en:
si las condiciones y las tareas permiten una fácil alineación. Aún así, prefiero la versión ternaria porque es más corta y no tiene tanto ruido en torno a las condiciones y tareas.
fuente
ReSharper en VS.NET a veces sugiere reemplazar
if...else
con el?:
operador.Parece que ReSharper sugiere solo si las condiciones / bloques están por debajo de un cierto nivel de complejidad, de lo contrario se mantiene
if...else
.fuente
Esto se puede reformatear para que sea tan atractivo como la combinación if / else:
Pero el problema es que no estoy realmente seguro si obtuve la sangría correcta para representar lo que realmente sucederá. :-)
fuente
if-else
estructura equivalente . La clave es el formateo.Lejos de ser malvado, el operador ternario es un regalo del cielo.
Es más útil cuando desea tomar una decisión en una expresión anidada . El ejemplo clásico es una llamada de función:
En su ejemplo particular, el ternario es casi gratuito, ya que es la expresión de nivel superior bajo a
return
. Puede levantar el condicional al nivel de instrucción sin duplicar nada más que lareturn
palabra clave.NB Nada hará que ese algoritmo particular para la mediana sea fácil de leer.
fuente
printf("I see %d evil construct%s in this program\n", n, "s" unless (n == 1) "s");
Dejando a un lado los argumentos "malvados", en mi experiencia he encontrado una alta correlación entre el uso de un programador del operador ternario y la probabilidad de que toda su base de código sea difícil de leer, seguir y mantener (si no es indocumentada). Si un programador está más preocupado por guardar unas pocas líneas de 1-2 caracteres que alguien que pueda entender su código, entonces cualquier confusión menor que comprenda una declaración ternaria suele ser la punta del iceberg.
Los operadores ternarios atraen números mágicos como s ** t atrae moscas.
Si estaba buscando una biblioteca de código abierto para resolver un problema particular, y veía código como los operadores ternarios del póster original en un candidato para dicha biblioteca, las campanas de advertencia comenzarían a sonar en mi cabeza y comenzaría a considerar seguir adelante a otro proyecto para pedir prestado.
fuente
Aquí hay un ejemplo de cuándo es malo:
Es confuso y derrochador. El compilador podría optimizar la segunda expresión (oldValue = oldValue), pero ¿por qué el codificador hizo esto en primer lugar?
Otra doozy:
Algunas personas simplemente no están destinadas a ser codificadores ...
Greg dice que el enunciado if equivalente es 'ruidoso'. Es si lo escribes ruidosamente. Pero eso mismo si se puede escribir como:
Que no es más ruidoso que el ternario. Me pregunto si los atajos ternarios; Cómo se evalúan todas las expresiones?
fuente
if (x != 0) x = 0;
...¿Mal? Mira, son simplemente diferentes.
if
Es una declaración.(test ? a : b)
es una expresion. No son lo mismo.Existen expresiones para expresar valores. Existen declaraciones para realizar acciones. Las expresiones pueden aparecer dentro de las declaraciones, pero no al revés. Por lo tanto, puede usar expresiones ternarias dentro de otras expresiones, como para términos en una suma, o para argumentos de un método, y así sucesivamente. No tiene que hacerlo , pero puede hacerlo si lo desea . No hay nada de malo en eso. Algunas personas pueden decir que eso es malo, pero esa es su opinión.
Un valor de una expresión ternaria es que le permite manejar casos verdaderos y falsos.
if
las declaraciones no lo hacen.Si le preocupa la legibilidad, puede formatearlos de manera legible.
De alguna manera, el "mal" se introdujo en el vocabulario de programación. Me encantaría saber quién lo dejó caer por primera vez. (En realidad, tengo un sospechoso: está en el MIT). Preferiría que tuviéramos razones objetivas para los juicios de valor en este campo, no solo el gusto de las personas y los insultos.
fuente
Tiene un lugar. He trabajado en muchas compañías donde los niveles de habilidad de los desarrolladores varían desde terribles hasta magos. Dado que el código debe mantenerse y no estaré allí para siempre, trato de escribir cosas para que parezca que pertenece allí (sin mirar los comentarios con mis iniciales, es extremadamente raro que pueda mira el código en el que he trabajado para ver dónde hice los cambios) y que alguien con menos habilidad que yo pueda mantenerlo.
Si bien el operador ternario se ve nitido y genial, mi experiencia es que la línea de código será casi imposible de mantener. En mi empleador actual, tenemos productos que se han estado enviando durante casi 20 años. No usaría ese ejemplo en ningún lado.
fuente
No creo que el operador ternario sea malo.
Sin embargo, aquí hay una trampa que me dejó perplejo. Fui programador en C para muchos (10+) y a fines de la década de 1990 me mudé a la programación de aplicaciones basadas en la web. Como programador web, pronto me encontré con PHP, que también tiene un operador ternario. Tuve un error en un programa PHP que finalmente rastreé hasta una línea de código con un operador ternario anidado. Resulta que el operador ternario PHP asociado de izquierda a derecha, pero el operador ternario C (al que estaba acostumbrado) se asocia de derecha a izquierda.
fuente
Cualquier cosa que haga tu código más feo es malo.
Si usa ternary para hacer su código más limpio, entonces úselo. A veces, como PHP, es genial hacer sustituciones en línea, por ejemplo
Eso ahorra algunas líneas, y es bastante claro, pero su ejemplo necesita al menos un mejor formato para ser claro, y el ternario no es realmente bueno para líneas múltiples, entonces también podría usar if / else.
fuente
¿Puedo decirlo? No puedo encontrar esta aplicación particular de la operación ternaria evil :
Por favor, ten piedad, mi reputación ya es bastante lamentable.
fuente
Mayor victoria: muestra que hay un único objetivo de acción.
Hay dos rutas de código que puede seguir, y el lector debe leer cuidadosamente para ver qué dos variables se están configurando. En este caso, es solo una variable, pero el lector tiene más que leer para resolverlo. Después de todo, podría haber sido esto:
Con el operador ternario, está claro que solo se está configurando una variable.
En el nivel más bajo, es el principio SECO (No repetir) en su forma más básica. Si
$foo
solo puede especificar una vez, hágalo.fuente
Si ... entonces ... más tiende a enfatizar la condición y, por lo tanto, desestima las operaciones que se realizan condicionalmente.
el operador ternario es lo contrario, tiende a ocultar la condición y, por lo tanto, es útil cuando la operación que se realiza es más importante que la condición misma.
Existe un pequeño inconveniente técnico, en algunos lenguajes, de que no son intercambiables debido a que uno es una declaración y otro una expresión, por ejemplo, inicializando condicionalmente consts en C ++
fuente
Creo que cuando se desarrolla para un grupo homogéneo de personas, no hay ningún problema, pero cuando se tiene que tratar con personas que manejan diferentes niveles, este tipo de línea solo introduce un nivel adicional de complexyti al código. Entonces, mi política al respecto es: código claro y no explicar en lugar de código corto y explicar 123123 veces.
No debería enseñarme a los principiantes, más bien los prefiero para que lo descubran cuando surja la necesidad, por lo que se usará solo cuando sea necesario y no cada vez que necesite un if.
fuente
En mi opinión, el operador en sí no es malo, pero la sintaxis utilizada para él en C (y C ++) es excesivamente breve. En mi opinión, Algol 60 lo hizo mejor, así que algo como esto:
se parecería más a esto (pero se adhiere a la sintaxis tipo C en general):
Incluso con eso, el anidamiento excesivamente profundo puede conducir a problemas de legibilidad, pero al menos A) cualquiera que haya hecho la programación puede resolverlo de manera simple, y B) las personas que lo entienden pueden manejar un anidamiento considerablemente más profundo con bastante facilidad. OTOH, también notaría que en LISP (por ejemplo) a
cond
es más o menos como una declaración ternaria, no un conjunto de declaraciones, sino una sola expresión que produce un valor (de nuevo, la mayoría de LISP es así ... .)fuente
A = (x==y) ? B : C
Una tienda que escribe regularmente métodos de 600-1200 líneas no debería decirme que un ternario es "difícil de entender". Cualquier tienda que regularmente permita cinco condiciones para evaluar una rama de código no debería decirme que las condiciones concretamente resumidas en un ternario son "difíciles de leer".
fuente
¿Cuándo es?: ¿Apropiado y cuándo no?
¿Debería enseñarse u ocultarse a los principiantes?
No importa, pero no debe ocultarse intencionalmente ya que no es demasiado complejo para que un "principiante" aprenda.
fuente
En tu ejemplo:
es muy simple de leer y obvio. La variable entre <<es el valor de retorno.
Actualizar
igual, pero menos líneas de código. Todavía simple, creo.
fuente
También es necesario para const
fuente
const
es así en ciertos idiomas. En C #const
siempre se debe compilar el tiempo de valor conocido. lo que significa queconst int nLegs = isChicken ? 2: 4 ;
no funcionará, pero loconst int nLegs = true ? 2: 4 ;
hará