Pregunta

Hoy, un compañero de trabajo me sugirió que refactorizara mi código para usar una declaración de etiqueta para controlar el flujo a través de 2 bucles for anidados que había creado.Nunca los he usado antes porque personalmente creo que disminuyen la legibilidad de un programa.Sin embargo, estoy dispuesto a cambiar de opinión acerca de su uso si el argumento es lo suficientemente sólido.¿Cuáles son las opiniones de la gente sobre las declaraciones de las etiquetas?

¿Fue útil?

Solución

Muchos algoritmos se expresan más fácilmente si se pueden saltar dos bucles (o un bucle que contiene una instrucción de cambio).No te sientas mal por eso.Por otro lado, puede indicar una solución demasiado compleja.Así que retroceda y observe el problema.

Algunas personas prefieren un enfoque de "entrada única, salida única" para todos los bucles.Es decir, evitar por completo la interrupción (y la continuación) y el retorno anticipado de los bucles.Esto puede resultar en algún código duplicado.

Lo que evitaría enfáticamente es introducir variables auxiliares.Ocultar el flujo de control dentro del estado aumenta la confusión.

Dividir bucles etiquetados en dos métodos puede resultar complicado.Las excepciones probablemente sean demasiado pesadas.Pruebe un enfoque de entrada única y salida única.

Otros consejos

Las etiquetas son como las de goto:Úselos con moderación y solo cuando hagan que su código sea más rápido y más importante, más comprensible,

por ejemplo, si está en bucles grandes de seis niveles de profundidad y encuentra una condición que hace que no tenga sentido completar el resto del bucle, no tiene sentido tener 6 trampillas adicionales en sus declaraciones de condición para salir del bucle antes.

Las etiquetas (y los goto) no son malos, es solo que a veces la gente los usa de mala manera.La mayoría de las veces intentamos escribir nuestro código para que sea comprensible para usted y el próximo programador que venga.Hacerlo súper rápido es una preocupación secundaria (tenga cuidado con la optimización prematura).

Cuando las etiquetas (y los goto) se usan incorrectamente, hacen que el código sea menos legible, lo que causa molestias a usted y al próximo desarrollador.Al compilador no le importa.

Hay pocas ocasiones en las que necesitas etiquetas y pueden resultar confusas porque rara vez se utilizan.Sin embargo, si necesita usar uno, úselo.

POR CIERTO:esto se compila y se ejecuta.

class MyFirstJavaProg {  
        public static void main(String args[]) {
           http://www.javacoffeebreak.com/java101/java101.html
           System.out.println("Hello World!");
        }
}

Tengo curiosidad por saber cuál es su alternativa a las etiquetas.Creo que esto se reducirá en gran medida al argumento de "regresar lo antes posible" vs."use una variable para contener el valor de retorno y solo regrese al final".

Las etiquetas son bastante estándar cuando tienes bucles anidados.La única forma en que realmente disminuyen la legibilidad es cuando otro desarrollador nunca los ha visto antes y no entiende lo que significan.

Nunca he visto etiquetas utilizadas "en la naturaleza" en el código Java.Si realmente desea romper con los bucles anidados, vea si puede refactorizar su método para que una declaración de devolución temprana haga lo que desea.

Técnicamente, supongo que no hay mucha diferencia entre una devolución anticipada y una etiqueta.Sin embargo, prácticamente todos los desarrolladores de Java han visto un retorno temprano y saben lo que hace.Supongo que muchos desarrolladores al menos se sorprenderían con una etiqueta y probablemente se confundirían.

En la escuela me enseñaron la ortodoxia de entrada única y salida única, pero desde entonces he llegado a apreciar las declaraciones de retorno tempranas y la ruptura de bucles como una forma de simplificar el código y hacerlo más claro.

Yo argumentaría a favor de ellos en algunas ubicaciones; los encontré particularmente útiles en este ejemplo:


nextItem: for(CartItem item : user.getCart()) {

  nextCondition : for(PurchaseCondition cond : item.getConditions()) {
     if(!cond.check())
        continue nextItem;
     else
        continue nextCondition;

  }
  purchasedItems.add(item);
}

Creo que con el nuevo bucle for-each, la etiqueta puede quedar muy clara.

Por ejemplo:

sentence: for(Sentence sentence: paragraph) {
  for(String word: sentence) {
    // do something
    if(isDone()) {
      continue sentence;
    }
  }
}

Creo que queda muy claro si tu etiqueta es la misma que tu variable en el nuevo for-each.De hecho, tal vez Java debería ser malvado y agregar etiquetas implícitas para cada variable, je.

Utilicé un bucle etiquetado de Java para implementar un método Sieve para encontrar números primos (hecho para uno de los problemas matemáticos del proyecto Euler), lo que lo hizo 10 veces más rápido en comparación con los bucles anidados.Por ejemplo, si (cierta condición) vuelve al bucle exterior.

private static void testByFactoring() {
    primes: for (int ctr = 0; ctr < m_toFactor.length; ctr++) {
        int toTest = m_toFactor[ctr];
        for (int ctr2 = 0; ctr2 < m_divisors.length; ctr2++) {
            // max (int) Math.sqrt(m_numberToTest) + 1 iterations
            if (toTest != m_divisors[ctr2]
                        && toTest % m_divisors[ctr2] == 0) {
                continue primes; 
            }
        } // end of the divisor loop
    } // end of primes loop
} // method

Le pregunté a un programador de C++ qué tan malos son los bucles etiquetados y dijo que los usaría con moderación, pero que ocasionalmente pueden resultar útiles.Por ejemplo, si tiene 3 bucles anidados y, en determinadas condiciones, desea volver al bucle más externo.

Entonces tienen sus usos, depende del problema que intentabas resolver.

Nunca uso etiquetas en mi código.Prefiero crear una guardia e inicializarla para nulo u otro valor inusual.Esta guardia suele ser un objeto de resultado.No he visto a ninguno de mis compañeros de trabajo usando etiquetas ni encontré ninguna en nuestro repositorio.Realmente depende de tu estilo de codificación.En mi opinión, el uso de etiquetas disminuiría la legibilidad ya que no es una construcción común y generalmente no se usa en Java.

Sí, debes evitar el uso de etiquetas a menos que haya una razón específica para usarlas (el ejemplo de cómo simplifica la implementación de un algoritmo es pertinente).En tal caso, recomendaría agregar suficientes comentarios u otra documentación para explicar el razonamiento detrás de esto, de modo que alguien no venga más tarde y lo estropee con alguna noción de "mejorar el código" o "deshacerse del olor a código" o alguna otra excusa potencialmente tonta.

Yo equipararía este tipo de preguntas con decidir cuándo se debe o no usar el if ternario.La razón principal es que puede impedir la legibilidad y, a menos que el programador tenga mucho cuidado al nombrar las cosas de una manera razonable, el uso de convenciones como etiquetas podría empeorar mucho las cosas.Supongamos que el ejemplo que usa 'nextCondition' y 'nextItem' hubiera usado 'loop1' y 'loop2' para los nombres de sus etiquetas.

Personalmente, las etiquetas son una de esas características que no tienen mucho sentido para mí, fuera de Assembly o BASIC y otros lenguajes igualmente limitados.Java tiene muchas construcciones de control y bucles más convencionales/regulares.

Encontré que las etiquetas a veces son útiles en las pruebas, para separar las fases habituales de configuración, ejercicio y verificación y declaraciones relacionadas con el grupo.Por ejemplo, usando la terminología BDD:

@Test
public void should_Clear_Cached_Element() throws Exception {
    given: {
        elementStream = defaultStream();
        elementStream.readElement();
        Assume.assumeNotNull(elementStream.lastRead());
    }
    when:
        elementStream.clearLast();
    then:
        assertThat(elementStream.lastRead()).isEmpty();
}

Sus opciones de formato pueden variar, pero la idea central es que las etiquetas, en este caso, proporcionen una distinción notable entre las secciones lógicas que componen su prueba, mejor que los comentarios.Pienso que el Spock La biblioteca simplemente se basa en esta misma característica para declarar sus fases de prueba.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top