Enums e Pattern Matching
Um enum define um tipo como uma entre várias variantes nomeadas. Diferente dos enums de muitas linguagens, que são só números rotulados, os do Rust podem ser comparados exaustivamente com match, e cada variante pode até carregar seus próprios dados.
enum Direction {
Up,
Down,
Left,
Right,
}
fn describe(dir: Direction) -> &'static str {
match dir {
Direction::Up => "going up",
Direction::Down => "going down",
Direction::Left => "going left",
Direction::Right => "going right",
}
}
fn main() {
println!("{}", describe(Direction::Left));
}going left
match compara um valor contra cada variante por vez, e o compilador verifica que cada variante possível está coberta — deixe uma de fora, e será um erro de compilação, não um bug esperando para acontecer em tempo de execução.
Enums que carregam dados
Cada variante de um enum pode conter seus próprios dados com seu próprio formato — Shape::Circle carrega um único f64, enquanto Shape::Rectangle carrega dois. match desestrutura qualquer variante que esteja realmente presente, vinculando seus dados a um nome que você pode usar diretamente.
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn area(shape: Shape) -> f64 {
match shape {
Shape::Circle(radius) => 3.14159 * radius * radius,
Shape::Rectangle(w, h) => w * h,
}
}
fn main() {
println!("{:.2}", area(Shape::Circle(2.0)));
println!("{:.2}", area(Shape::Rectangle(3.0, 4.0)));
}12.57 12.00
Próximo: Option e Result — como o Rust substitui null e exceções por dois enums comuns.
Practice Exercise
Defina um enum Status com as variantes Active e Inactive. Escreva uma função label(status: Status) -> &'static str que retorne "online" para Active e "offline" para Inactive usando match. Imprima label(Status::Active).