¿Por qué este patrón de coincidencia es inalcanzable cuando se utilizan patrones no literales?

Resuelto Mike Vella asked hace 9 años • 1 respuestas

El siguiente código ( patio de juegos )

let max_column = 7;
edge = match current_column {
    0 => Edge::Left,
    max_column => Edge::Right,
    _ => Edge::NotAnEdge
};

da como resultado la siguiente advertencia:

warning: unreachable pattern
  --> src/main.rs:10:9
   |
9  |         max_column => Edge::Right,
   |         ---------- matches any value
10 |         _ => Edge::NotAnEdge
   |         ^ unreachable pattern
   |
   = note: #[warn(unreachable_patterns)] on by default

Reemplazar la variable max_columncon el literal funciona bien:

let max_column = 7;
edge = match current_column {
    0 => Edge::Left,
    7 => Edge::Right,
    _ => Edge::NotAnEdge
};

¿Por qué es _inalcanzable en el primer ejemplo cuando se puede alcanzar para cualquier valor donde current_column != max_column?

Mike Vella avatar Jan 30 '15 05:01 Mike Vella
Aceptado

El lenguaje de programación Rust explica cómomatchse procesa una expresión, el énfasis es mío:

Cuando se matchejecuta la expresión, compara el valor resultante con el patrón de cada brazo, en orden .

En su ejemplo, max_columnes el nombre de la variable a vincular, no una constante o una variable externa. Cuando el compilador llegue a max_column, los valores restantes se asignarán a ese brazo del partido, lo que hará que los brazos posteriores sean inalcanzables.

En tu caso, quieres hacer max_columnuna constante real:

let current_column = 1;
const MAX_COLUMN: i32 = 7;
edge = match current_column {
    0          => Edge::Left,
    MAX_COLUMN => Edge::Right,
    _          => Edge::NotAnEdge
};

O si eso no es posible, quieres un guardia de partido :

let current_column = 1;
let max_column = 7;
edge = match current_column {
    0                    => Edge::Left,
    a if a == max_column => Edge::Right,
    _                    => Edge::NotAnEdge
};

Tenga en cuenta que, como primera aproximación, a¡y _son lo mismo en este caso! En ambos casos, la variable coincidente estará vinculada a un nombre ( ao _respectivamente), pero cualquier identificador con el prefijo _está en mayúsculas especiales para usarse como marcador de posición de variable no utilizado.

Bluss aclara y corrige esta aproximación :

_Es un caso especial separado, no es un enlace variable en absoluto, ¡pero es la ausencia de uno! Hacer coincidir contra _xmueve el valor a _x, _no hace tal cosa. (La diferencia es observable.)

Shepmaster avatar Jan 29 '2015 22:01 Shepmaster