Saltar al contenido principal

Repeticiones o bucles

  • Rust tiene tres tipos de bucles; loop, while y for
  • break para interrumpir un bucle
  • continue para saltar a la siguiente iteración
  • return para salir de funciones, también se puede hacer desde dentro de un loop

loop

  • Bucle infinito o hasta detenerlo explícitamente
  • Similar a un bucle while(true)
  • Para salir del bucle se utiliza break
loop {
println!("Loop");
  break;
}

Retornando valores

  • Pueden devolver un valor, el valor se anota después del break
  • Uno de los usos de loopes volver a intentar una operación que se sabe que podría fallar, como verificar si un subproceso ha completado su trabajo o al pedir información al usuario y este ingresa datos no válidos, como letras en lugar de números
fn main() {
    let mut counter = 0;
    let result = loop {
        counter += 1;

        // Cuando se cumple, termina el bucle
        if counter == 10 {
            break counter * 2; // Retornando un valor
        }
    };

    println!("The result is {result}"); // 20
}

Loop anidado y etiquetado

  • Se etiquetan los loops anidados para evitar confusiones
  • Las etiquetas se usan en el break o continue para especificar a qué bucle se debe aplicar y no al más interno
  • Las etiquetas deben comenzar con una comilla simple, ejemplo: 'bucle_externo
  • break y continue sin etiquetas se aplica al bucle más interno en ese punto
fn main() {
    let mut contador_externo = 0;

    // Bucle externo etiquetado como 'bucle_externo
    'bucle_externo: loop {
        println!("Contador del bucle externo: {contador_externo}");
        let mut contador_interno = 10;

        // Bucle interno
        loop {
            println!("Cuenta regresiva del bucle interno: {contador_interno}");

            // Salir del bucle interno cuando el contador llega a 9
            if contador_interno == 9 {
                println!("Saliendo del bucle interno");
                break;
            }

            // Salir de ambos bucles cuando el contador externo es 2
            if contador_externo == 2 {
                println!("Contador externo llegó a 2, saliendo de ambos bucles");
                break 'bucle_externo; // <======================== etiquetado
            }

            contador_interno -= 1;
        }

        // Incrementar el contador del bucle externo
        // después de cada iteración completa del bucle interno
        contador_externo += 1;
        println!("Completada una iteración del bucle externo\n");
    }

    // Imprimir el valor final del contador externo
    println!("Contador externo final: {contador_externo}");
}

while bucles condicionales

  • El código se ejecuta repetidamente mientras la condición sea true
  • Cuando deja de ser true el programa o código llama automáticamente a break
  • Es posible implementar manualmente este comportamiento utilizando loop, if, else y break
fn main() {
    let mut number = 5;
   
    while number != 0 {
        println!("{}!", number);
        number -= 1;
    }
   
    println!("End.");
}
  • También se puede utilizar while para recorrer una colección, como una matriz (array)
  • Este enfoque es propenso a errores porque se puede intentar acceder a un índice no válido
  • También es lento, porque el compilador agrega código de tiempo de ejecución para realizar la verificación condicional de si el índice está dentro de los límites de la matriz en cada iteración a través del bucle.
  • Como alternativa utilizar el bucle for
fn main() { 
let a = [10, 20, 30, 40, 50];
let mut index = 0;

while index < 5 {
println!("the value is: {}", a[index]);
index += 1;
}
}

for recorriendo colecciones

  • Se utiliza para recorrer una colección de elementos, como un array
  • Se puede utilizar con rangos
  • Se puede utilizar como iterador

Como iterador

  • Es más seguro que utilizar while porque se elimina la posibilidad de errores que podrían resultar de ir más allá del final de la matriz o de no ir lo suficientemente lejos y perder algunos elementos
fn main() {

    let letras = ['a', 'b', 'c', 'd', 'e'];
    for element in letras {
        println!("Letra: {element}");
    }

}

Con rangos

  • Para ejecutar el código cierta cantidad de veces, como una cuenta regresiva
  • La forma de hacerlo es con un Range de la biblioteca estándar que genera todos los números en secuencia, comenzando desde un número y terminando antes de otro
  • (En el ejemplo, rev se utiliza para invertir el rango)
fn main() {

    for number in (1..5).rev() {
        println!("{}!", number); // 4, 3, 2 y 1
    }

}