Historia de la pregunta
El operador match en Rust es una herramienta poderosa de coincidencia de patrones, tomada de los lenguajes funcionales. A diferencia de los equivalentes en C/C++, en Rust se realiza una estricta verificación de exhaustividad, y para cada posible caso se deben proporcionar ramas correspondientes.
Problema
Los errores al trabajar con match están más relacionados con no considerar todos los casos del tipo (por ejemplo, enum), un mal manejo de las guardias (condiciones en las ramas) o una estructura anidada compleja. Un tratamiento incorrecto puede llevar a errores en tiempo de compilación o a una lógica implícitamente incorrecta.
Solución
_).if después del patrón).Ejemplo de código:
enum Shape { Circle(f64), Rectangle { width: f64, height: f64 }, } fn print_area(s: Shape) { match s { Shape::Circle(r) if r > 0.0 => println!("area = {}", 3.14 * r * r), Shape::Rectangle { width, height } if width > 0.0 && height > 0.0 => println!("area = {}", width * height), _ => println!("invalid shape"), } }
Características clave:
¿Afecta el orden de las ramas en match a la ejecución?
Sí, el orden de las ramas es importante: una vez que se encuentra la primera coincidencia, las posteriores no se verifican. Esto es especialmente crítico con las pattern guard; si hay una rama con guardia antes, interceptará el valor antes de la catch-all.
¿Es obligatorio el catch-all (_) en match por enum?
No, si has considerado explícitamente todos los casos (y los propios variantes de declaración del tipo no cambiarán con el tiempo). Sin embargo, se necesita catch-all al tratar con tipos que pueden tener valores adicionales o cuando no se desea tratar todas las ramas explícitamente.
¿Se pueden usar varios patrones (alternativas) en una sola rama de match?
Sí. A través de una barra vertical (|) se pueden combinar patrones:
match x { 1 | 2 | 3 => println!("uno, dos o tres"), _ => println!("algo más"), }
_ demasiado pronto (antes de ramas específicas).Un desarrollador escribió match con catch-all al principio y no pudo manejar correctamente los casos específicos.
Pros:
El programa compila.
Contras:
La lógica específica nunca funciona, parte del código no se cubre.
Tratamiento explícito de todos los casos de enum, catch-all solo como la última rama, guardias separadas para casos atípicos.
Pros:
Previsibilidad, el compilador ayuda a no olvidar un caso, fácil de extender tipos.
Contras:
Código de plantilla adicional en caso de muchas variantes.