Lições do módulo (2/2)
Correspondência de padrões, opção e resultado
Rust tem um mecanismo de fluxo de controle extremamente poderoso chamado correspondência de padrões. Ele permite comparar um valor com uma série de padrões e executar código com base no padrão correspondente.
A Declaração match
A instrução match em Rust é semelhante a switch em outras linguagens, mas muito mais poderosa e segura. O compilador garante que a correspondência seja exaustiva, o que significa que todos os casos possíveis devem ser tratados:
enum Direction {
North,
South,
East,
West,
}
let dir = Direction::East;
match dir {
Direction::North => println!("Andiamo a Nord"),
Direction::South => println!("Andiamo a Sud"),
Direction::East => println!("Andiamo a Est"),
Direction::West => println!("Andiamo a Ovest"),
}Lidando com ausência de valor: Option
Rust não possui o conceito de valor nulo (null ou nil). Em vez disso, a biblioteca padrão define uma enumeração chamada Option<T> que pode conter:
Some(T): contém um valor do tipoT.None: indica ausência de valor.
let x: Option<i32> = Some(5);
let y: Option<i32> = None;
match x {
Some(val) => println!("C'e un valore: {}", val),
None => println!("Nessun valore trovato"),
}Tratamento de erros recuperáveis: Result
Para operações que podem falhar (como ler um arquivo ou analisar uma string em um número), Rust usa o enum Result<T, E>, que tem duas variantes:
Ok(T): a operação foi bem-sucedida e contém o valor de sucessoT.Err(E): a operação falhou e contém o erroE.
fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
if denominator == 0.0 {
Err(String::from("Divisione per zero!"))
} else {
Ok(numerator / denominator)
}
}Graças ao compilador Rust, você é forçado a lidar com o caso Err antes de poder acessar o valor dentro de Ok, evitando muitos bugs comuns de tempo de execução.
O padrão curinga _
Ao trabalhar com tipos de dados que possuem um grande número de variantes (como números inteiros), é impossível listar todos os casos em um match. Rust permite usar o caractere curinga _ para capturar todos os casos restantes não definidos explicitamente:
let some_u8 = 3u8;
match some_u8 {
1 => println!("One"),
2 => println!("Two"),
_ => println!("Something else"), // Handles all other values
}Experimente você mesmo
Declare uma variável chamada talvez_valor do tipo Option<i32> contendo Some(42). Use uma instrução de correspondência em talvez_valor: se contiver Some(v) imprima 'valor é: v' (usando println!), se contiver None imprima 'nenhum valor'.
Mostrar dica
Escreva um bloco `match Maybe_value { Some(v) => println!('value is: {}', v), None => println!('no value') }`.
Solução disponível após 3 tentativas
Complete a função check_age para que ela retorne Ok('Adult') se a idade for maior ou igual a 18, e Err('Minor') caso contrário.
Mostrar dica
Use `if age >= 18` para decidir se deseja retornar`Ok('Adulto')`ou`Err('Menor')`.
Solução disponível após 3 tentativas
Declare uma enumeração chamada Status contendo as variantes Ativa e Inativa. Em main, declare uma variável current_status com o valor Status::Active. Finalmente, use uma instrução match em current_status para imprimir 'ativo' se o status for Ativo ou 'inativo' se o status for Inativo.
Mostrar dica
Defina o enum antes de main com `enum Status {Active, Inactive}`. Em main, use `let current_status = Status::Active;`e execute o`match` nas variantes.
Solução disponível após 3 tentativas