Pregunta

En muchos idiomas las tareas son legales en condiciones. Nunca entendí la razón detrás de esto. ¿Por qué escribirías:

if (var1 = var2) {
  ...
}

en lugar de:

var1 = var2;
if (var1) {
  ...
}
¿Fue útil?

Solución

Es más útil para los bucles que las declaraciones if.

while( var = GetNext() )
{
  ...do something with var 
}

Que de otro modo tendría que escribirse

var = GetNext();
while( var )
{
 ...do something
 var = GetNext();
}

Otros consejos

Es más útil si está llamando a una función:

if (n = foo())
{
    /* foo returned a non-zero value, do something with the return value */
} else {
    /* foo returned zero, do something else */
}

Claro, puedes poner el n = foo (); en una declaración separada, entonces if (n), pero creo que lo anterior es un lenguaje bastante legible.

Lo encuentro más útil en cadenas de acciones que a menudo involucran detección de errores, etc.

if ((rc = first_check(arg1, arg2)) != 0)
{
    report error based on rc
}
else if ((rc = second_check(arg2, arg3)) != 0)
{
    report error based on new rc
}
else if ((rc = third_check(arg3, arg4)) != 0)
{
    report error based on new rc
}
else
{
    do what you really wanted to do
}

La alternativa (no usar la asignación en la condición) es:

rc = first_check(arg1, arg2);
if (rc != 0)
{
    report error based on rc
}
else
{
    rc = second_check(arg2, arg3);
    if (rc != 0)
    {
        report error based on new rc
    }
    else
    {
        rc = third_check(arg3, arg4);
        if (rc != 0)
        {
            report error based on new rc
        }
        else
        {
            do what you really wanted to do
        }
    }
}

Con la comprobación de errores prolongada, la alternativa puede ejecutarse fuera del RHS de la página, mientras que la versión de asignación en condicional no hace eso.

Las comprobaciones de error también podrían ser 'acciones' - first_action () , second_action () , third_action () - por supuesto, más bien que solo cheques. Es decir, podrían verificarse los pasos en el proceso que gestiona la función. (La mayoría de las veces en el código con el que trabajo, las funciones están en la línea de las verificaciones previas a la condición, o las asignaciones de memoria necesarias para que la función funcione, o en líneas similares).

Puede ser útil si está llamando a una función que devuelve datos para trabajar o un indicador para indicar un error (o que ya ha terminado).

Algo como:

while ((c = getchar()) != EOF) {
    // process the character
}

// end of file reached...

Personalmente es un idioma que no me gusta mucho, pero a veces la alternativa es más fea.

GCC puede ayudarlo a detectar (con -Wall) si accidentalmente intenta usar una asignación como un valor de verdad, en caso de que le recomiende escribir

if ((n = foo())) {
   ...
}

I.e. use paréntesis adicionales para indicar que esto es realmente lo que quiere.

El modismo es más útil cuando se escribe un bucle while en lugar de una instrucción if . Para una declaración if , puede dividirla como lo describe. Pero sin esta construcción, tendrías que repetirlo:

c = getchar();
while (c != EOF) {
    // ...
    c = getchar();
}

o use una estructura de bucle y medio:

while (true) {
    c = getchar();
    if (c == EOF) break;
    // ...
}

Por lo general, preferiría la forma de bucle y medio.

La respuesta corta es que Los lenguajes de programación orientados a la expresión permiten un código más sucinto. No lo obligan a separar los comandos de las consultas .

En PHP, por ejemplo, es útil para recorrer los resultados de la base de datos SQL:

while ($row = mysql_fetch_assoc($result)) {
    // Display row
}

Esto se ve mucho mejor que:

$row = mysql_fetch_assoc($result);
while ($row) {
    // Display row
    $row = mysql_fetch_assoc($result);
}

La otra ventaja viene durante el uso de gdb. En el siguiente código no se conoce el código de error si tuviéramos un solo paso.

while (checkstatus() != -1) {
    // process
}

Más bien

while (true) {
    int error = checkstatus();
    if (error != -1)
        // process
    else
        //fail
}

Ahora, durante un solo paso, podemos saber cuál fue el código de error de retorno de checkstatus ().

El motivo es:

  1. Mejora del rendimiento (a veces)

  2. Código menor (siempre)

Tome un ejemplo: hay un método someMethod () y en una condición if desea verificar si el valor de retorno del método es nulo . Si no, va a usar el valor de retorno nuevamente.

If(null != someMethod()){
    String s = someMethod();
    ......
    //Use s
}

Esto obstaculizará el rendimiento ya que está llamando al mismo método dos veces. En su lugar use:

String s;
If(null != (s = someMethod())) {
    ......
    //Use s
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top