Pattern Matching
Exhaustive pattern matching with match expressions, guards, and nested patterns.
Pattern matching
La expresion match proporciona pattern matching exhaustivo sobre valores. El compilador verifica que todos los casos esten cubiertos y advierte sobre brazos inalcanzables.
Matching basico
fn describe(x: i32) -> i64 {
match x {
0 => 0,
1 => 1,
_ => 2,
}
}
El comodin _ coincide con cualquier valor y se usa como caso por defecto.
Matching sobre enums
enum Shape {
Circle(f64),
Rectangle(f64, f64),
Triangle(f64, f64, f64),
}
fn sqrt(x: f64) -> f64 { x }
fn area(s: Shape) -> f64 {
match s {
Shape::Circle(r) => 3.14159 * r * r,
Shape::Rectangle(w, h) => w * h,
Shape::Triangle(a, b, c) => {
let s = (a + b + c) / 2.0
sqrt(s * (s - a) * (s - b) * (s - c))
},
}
}
Si se omite una variante, el compilador reporta un error de matching no exhaustivo.
Guards
Los brazos de un pattern pueden incluir guards con if para condiciones adicionales:
fn classify_temp(celsius: f64) -> i64 {
match celsius {
t if t < 0.0 => 0,
t if t < 20.0 => 1,
t if t < 35.0 => 2,
_ => 3,
}
}
Matching sobre structs
struct Point { x: f64, y: f64 }
fn quadrant(p: Point) -> i64 {
match p {
Point { x, y } if x > 0.0 && y > 0.0 => 1,
Point { x, y } if x < 0.0 && y > 0.0 => 2,
Point { x, y } if x < 0.0 && y < 0.0 => 3,
Point { x, y } if x > 0.0 && y < 0.0 => 4,
_ => 0,
}
}
Limitaciones actuales
- La desestructuracion de tuplas en bindings
let(let (a, b) = pair) aun no esta soportada. Usamatchen su lugar. - El pattern matching anidado sobre structs profundamente anidados funciona, pero la verificacion exhaustiva no cubre todos los casos aun.
- Los or-patterns (
A | B => ...) se parsean, pero la verificacion de cobertura para ellos todavia esta en desarrollo.