Destructuring
Destructuring unpacks structs, tuples, enums, and slices into bindings with patterns in let, match, and function parameters.
Receita
struct Point { x: i32, y: i32 }
fn main() {
let p = Point { x: 1, y: 2 };
let Point { x, y } = p;
println!("{x} {y}");
}Quando usar: Extrair campos de forma limpa, combinar dados aninhados e ignorar partes com ...
Exemplo Funcional
enum Shape {
Circle { radius: f64 },
Rect { w: f64, h: f64 },
}
fn area(s: &Shape) -> f64 {
match s {
Shape::Circle { radius } => std::f64::consts::PI * radius * radius,
Shape::Rect { w, h } => w * h,
}
}
fn main() {
let shapes = [Shape::Circle { radius: 2.0 }, Shape::Rect { w: 3.0, h: 4.0 }];
let total: f64 = shapes.iter().map(area).sum();
println!("{total}");
}O que isto demonstra:
- Destructuring de variantes de struct em
match - Referências
&Shapeevitam a movimentação - Destructuring de tuplas/arrays disponível de forma semelhante
- Bindings
@:n @ 1..=10captura o valor inteiro e o subpadrão
Mergulho Profundo
Ignorando Campos
let Point { x, .. } = p; // ignora y e o resto
let (_, second, ..) = tuple;Padrões Aninhados
match nested {
Outer::Inner(Point { x: 0, .. }) => {}
_ => {}
}ref / ref mut em Padrões
Vincula por referência dentro de match para evitar mover campos.
Armadilhas
- Movimentação no destructuring -
let s = structmove os campos. Correção:match &valou padrõesref. - Movimentação parcial de struct - Alguns campos movidos, outros não podem ser usados como um todo. Correção: Destructure todos os campos necessários ou empreste.
- Confusão de
..em struct vs match - A sintaxe de atualização..otherdifere do resto do padrão... Correção: O contexto determina o significado. - Padrões de struct não exaustivos - Deve listar todos os campos, a menos que
... Correção: Adicione..para ignorar o resto. - Alterações de modo de binding (edição) - Pode afetar a movimentação/cópia implícita. Correção: Leia a documentação de binding de padrões do Rust 2024.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
Acesso a campo p.x | Um ou dois campos | Muitos campos ou match aninhado |
| Métodos acessores | Encapsulamento | Structs de dados simples |
if let parcial | Variante única | Muitas formas |
| Registros via macro | Redução de boilerplate | derive padrão suficiente |
FAQs
Destructuring em argumentos de função?
`fn f(Point { x, y }: Point)` move a struct para a fn.Match de tupla?
`match pair { (0, y) => ..., _ => ... }`.Padrões de slice?
`[first, rest @ ..]` com padrões de slice (avançado).Guard com destructuring?
Combine em um braço de match: `Shape::Rect { w, h } if w == h`.Variante de tupla de enum?
`MyEnum::Tuple(a, b)` padrão.Ignorar com `_`?
`let (x, _) = pair` ignora o segundo.Destructuring mutável?
`let mut Point { x, .. } = p` muta os campos.ref mut?
`let Point { ref mut x, .. }` para empréstimo mutável parcial.Compatibilidade com serde?
Deserializar constrói structs - destructuring é uma preocupação separada.Performance?
Custo zero - compilado como acesso a campo.Relacionados
Versões da Stack: 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+.