Correspondência de Padrões com match
match compara um valor com padrões, vinculando variáveis e executando o primeiro braço correspondente. O compilador garante a exaustividade.
Receita
enum Color { Red, Green, Blue }
fn label(c: Color) -> &'static str {
match c {
Color::Red => "red",
Color::Green => "green",
Color::Blue => "blue",
}
}Quando usar isso: Enums, Option/Result, análise de tokens e ramificação múltipla com desestruturação.
Exemplo de Trabalho
#[derive(Debug)]
enum Token { Num(i64), Ident(String), Eof }
fn eval(tok: Token) -> String {
match tok {
Token::Num(n) if n < 0 => format!("negative {n}"),
Token::Num(n) => n.to_string(),
Token::Ident(name) => name,
Token::Eof => "eof".into(),
}
}
fn main() {
println!("{}", eval(Token::Num(-3)));
}O que isso demonstra:
- Vinculação de
n,namea partir de cargas úteis de variantes - Guarda
if n < 0refina o braço de correspondência - Braços exaustivos para todas as variantes
matchcomo expressão retornandoString
Mergulho Profundo
Formas de Padrão
- Literais, intervalos
1..=5 - Padrões de struct
Point { x, y } - Padrões de tupla e slice
- Vinculações
@n @ 1..=100 - Padrões
|ou-Some(0) | Some(1)
match vs if let
match lida com muitos padrões; if let lida com um padrão de forma ergonômica.
Armadilhas
- Variante ausente após alteração de enum - Erro de compilação entre crates. Correção: Atualize todas as correspondências (benefício da exaustividade).
- Modo de vinculação em Rust 2024 - Modos de vinculação
mutafetam a movimentação/cópia. Correção: Leia o guia de migração de edição para padrõesref/mut. - Inteiros não exaustivos -
match x: u8precisa de um braço_. Correção: Adicione curinga ou intervalos. - Movimentação no braço de correspondência - A vinculação move a menos que seja um padrão
ref. Correção: Useref/ref mutpara emprestar campos. - Guarda não pode emprestar o valor correspondente de forma estranha - A guarda é avaliada após a vinculação do padrão. Correção: Reestruture a guarda ou use uma cadeia
if let.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
if let / while let | Padrão único | Muitas variantes |
Macro matches! | Teste booleano | Necessita de valores vinculados |
let-else | Retorno antecipado em caso de incompatibilidade | Lógica complexa de múltiplos braços |
Cadeia if | Escalares simples | Enum com dados |
FAQs
Os braços devem retornar o mesmo tipo?
Sim, quando `match` é uma expressão.Posso corresponder a referências?
Sim: `match &opt { Some(v) => ..., None => ... }` com vinculações apropriadas.O que é `_`?
Curinga que ignora o valor, deve ser o último se usado sozinho.Padrões podem ser refutáveis?
`if let` e `let-else` lidam com padrões refutáveis; `match` requer cobertura.Correspondência em floats?
Permitido, mas sem intervalos de ordenação; use `partial_eq` ou codificação inteira.Deref em padrões?
Limitado; muitas vezes corresponde explicitamente a referências.Lint exaustivo para bool?
Não é necessário - bool é coberto por braços `true`/`false`.Desempenho?
Compilado para tabelas de salto/ramos - abstração de custo zero.Ordem das guardas de correspondência?
Os braços são testados de cima para baixo; a primeira correspondência vence.Cheiro de correspondência aninhada?
Achate com padrões combinados ou funções auxiliares.Relacionados
- Enums - variantes para corresponder
- if let, let else & while let - correspondência parcial
- Desestruturação - formas de padrão
- Option & Result como Enums - correspondências principais
Versões da Pilha: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.