A veces no necesitas un match completo con todos sus brazos: solo quieres hacer algo cuando el valor coincide con un patrón concreto. Para eso existen if let y while let, que combinan la potencia del pattern matching con una sintaxis más ligera.
if let básico
Compara este match con el if let equivalente:
// Con match
let numero = Some(7);
match numero {
Some(n) => println!("El número es {}", n),
None => (), // no hacemos nada
}
// Con if let
if let Some(n) = numero {
println!("El número es {}", n);
}
if let ejecuta el bloque solo si el patrón coincide. Si no coincide, simplemente no hace nada (o ejecuta el bloque else).
if let con else
let moneda = Some(25u32);
if let Some(valor) = moneda {
println!("Moneda de {} centavos", valor);
} else {
println!("Sin moneda");
}
Encadenar con else if let
enum Temperatura {
Celsius(f64),
Fahrenheit(f64),
}
let temp = Temperatura::Celsius(22.5);
if let Temperatura::Celsius(c) = temp {
println!("{}°C", c);
} else if let Temperatura::Fahrenheit(f) = temp {
println!("{}°F", f);
} else {
println!("Temperatura desconocida");
}
if let con Result
let resultado: Result<i32, &str> = Ok(42);
if let Ok(valor) = resultado {
println!("Éxito: {}", valor);
} else if let Err(e) = resultado {
println!("Error: {}", e);
}
while let: bucles condicionales
while let repite el bucle mientras el patrón coincida:
let mut pila = Vec::new();
pila.push(1);
pila.push(2);
pila.push(3);
while let Some(tope) = pila.pop() {
println!("{}", tope);
}
// Imprime: 3, 2, 1
Cuando pop() devuelve None (pila vacía), el bucle termina.
while let con canales
use std::sync::mpsc;
let (tx, rx) = mpsc::channel();
tx.send(1).unwrap();
tx.send(2).unwrap();
drop(tx); // cerramos el canal
while let Ok(msg) = rx.recv() {
println!("Recibido: {}", msg);
}
// Cuando el canal se cierra, recv() devuelve Err ? bucle termina
Cuándo elegir if let vs match
| Situación | Usar |
|---|---|
| Solo te importa un patrón | if let |
| Necesitas tratar todos los casos | match |
| Quieres exhaustividad que el compilador verifique | match |
| Repetir mientras coincida un patrón | while let |
| Dos o tres alternativas | if let / else if let |
| Cuatro o más alternativas | match (más legible) |
if let como alternativa a contains
let lista = vec![1, 2, 3, 4, 5];
if let Some(pos) = lista.iter().position(|&x| x == 3) {
println!("Encontrado en posición {}", pos);
}
Resumen
if let patrón = valor { }ejecuta el bloque solo si el patrón coincide.- Se puede combinar con
elseyelse if letpara múltiples alternativas. while letrepite el bucle mientras el patrón coincida.- Úsalos cuando la exhaustividad no es necesaria y quieres código más conciso.
- Para tres o más casos,
matchsuele ser más legible.
Con match, if let y while let tienes el conjunto completo de herramientas de pattern matching de Rust. El siguiente artículo explora los structs: cómo agrupar datos relacionados y añadir comportamiento con impl.
