En Rust, el control de flujo permite dictaminar la ejecución de las instrucciones mediante bucles. Aunque existen tres tipos principales, cada uno tiene un propósito semántico y técnico distinto para garantizar la claridad y la seguridad de la memoria.

El bucle loop es la forma más explícita de crear un bucle infinito. A diferencia de while true, usar loop comunica claramente al compilador y a otros programadores que el ciclo no depende de una condición booleana, sino de una lógica interna que probablemente use break para salir. Una característica única de loop en Rust es que puede actuar como una expresión: esto significa que puedes usar break seguido de un valor para que el bucle devuelva ese dato directamente a una variable. Si intentas usar un bucle para salir sin una condición de escape clara, el compilador de Rust te advertirá sobre el código potencialmente infinito.

El bucle while se utiliza cuando la iteración depende de una condición booleana. Se ejecuta mientras la condición sea true. Una variante fundamental es while let, que combina un bucle con el patrón de pattern matching. Se usa para iterar mientras un patrón (como el de un Option o un Result) coincida con el valor, permitiendo extraer datos de forma segura y elegante sin necesidad de usar match completo.

El bucle for es la forma más idiomática y segura de iterar en Rust. A diferencia de otros lenguajes que dependen de índices manuales que pueden causar errores fuera de rango, for itera sobre colecciones que implementan el trait IntoIterator. Esto permite recorrer elementos de un array, un vector o un rango (0..10) de forma segura. El bucle for puede tomar prestados los elementos (usando .iter()) o mover la propiedad del iterable, lo cual es crucial para entender la gestión de memoria en Rust.

fn main() {
    // 1. loop: Bucle infinito con retorno de valor
    let mut contador = 0;
    let resultado_loop = loop {
        contador += 1;
        if contador == 5 {
            break 100; // Rompe el bucle y devuelve 100
        }
    };
    println!("Resultado del loop: {}", resultado_loop);

    // 2. while: Bucle basado en condición booleana
    let mut n = 3;
    while n > 0 {
        println!("Cuenta regresiva: {}", n);
        n -= 1;
    }

    // 3. while let: Iterar mientras el patrón coincida
    let mut opcion = Some(10);
    while let Some(valor) = opcion {
        println!("Valor extraído: {}", valor);
        opcion = None; // Rompe el bucle al cambiar el patrón
    }

    // 4. for: Iteración idiomática con rangos y enumerate
    let frutas = ["manzana", "pera", "uva"];

    // Uso de rango (excluyente: de 0 a 2)
    for i in 0..3 {
        println!("Índice del rango: {}", i);
    }

    // Uso de enumerate para obtener índice y valor
    for (idx, fruta) in frutas.iter().enumerate() {
        println!("Posición {}: {}", idx, fruta);
    }
}

Explicación del Código


* resultado_loop: Variable que almacena el valor 100 devuelto por el bloque loop mediante la instrucción break 100.
* contador: Variable mutuable que incrementa en cada iteración de loop hasta alcanzar el valor de corte.
* n: Variable entera utilizada en el bucle while para controlar la condición n > 0.
* opcion: Variable de tipo Option<i32> que se utiliza con while let para desempaquetar el valor Some(10) y posteriormente convertirse en None, terminando el ciclo.
* i: Variable que representa el valor actual en la iteración del rango 0..3.
* idx y fruta: En el último for, se utiliza la desestructuración para asignar el índice actual a idx y una referencia al elemento de la colección frutas a fruta, gracias al método .enumerate().

22