Options, Some, None | Rust
- Options, Some, None | Rust
Em Rust, Option é um enum que representa um valor que pode ou não estar presente. Ele é uma maneira segura de lidar com a ausência de valores, sem recorrer ao uso de null, como em outras linguagens de programação. Aqui está um resumo de como Option funciona e como usá-lo.
Definição de Option
enum Option<T> {
Some(T),
None,
}
Some(T)é usado quando há um valor presente, ondeTé o tipo do valor.Nonerepresenta a ausência de valor.
Exemplo Básico
Exemplo simples:
fn main() {
let some_number: Option<i32> = Some(10);
let no_number: Option<i32> = None;
match some_number {
Some(n) => println!("Número encontrado: {}", n),
None => println!("Nenhum número"),
}
match no_number {
Some(n) => println!("Número encontrado: {}", n),
None => println!("Nenhum número"),
}
}
Neste exemplo, o código verifica se o Option contém um valor usando match. Isso garante um tratamento seguro para os dois casos: Some e None.
Usando Option em Funções:
Funções frequentemente retornam um Option para indicar que um resultado pode ou não estar disponível. Veja um exemplo de uma função que retorna um Option:
fn encontrar_elemento(arr: &[i32], alvo: i32) -> Option<usize> {
for (index, &valor) in arr.iter().enumerate() {
if valor == alvo {
return Some(index);
}
}
None
}
fn main() {
let arr = [1, 2, 3, 4, 5];
match encontrar_elemento(&arr, 3) {
Some(index) => println!("Encontrado no índice {}", index),
None => println!("Elemento não encontrado"),
}
}
Aqui, a função encontrar_elemento procura por um elemento no array. Se encontrar o valor, retorna Some(index), caso contrário, retorna None.
Métodos Comuns para Option
-
is_some()/is_none(): Verifica se oOptionéSomeouNone.let x = Some(5);
assert!(x.is_some());
assert!(!x.is_none()); -
map(): Transforma o valor dentro doOptionse ele forSome.let x = Some(5);
let y = x.map(|n| n * 2);
println!("{:?}", y); // Some(10) -
unwrap(): Obtém o valor dentro doOption, causando pânico se forNone.let x = Some(5);
let y = x.unwrap(); // 5
let no_value: Option<i32> = None;
let result = no_value.unwrap(); // Isso vai causar pânico! -
and_then(): Permite encadear operações no valor dentro de umOption.let x = Some(5);
let result = x.and_then(|n| if n > 10 { Some(n * 2) } else { None });
println!("{:?}", result); // None -
unwrap_or(): Retorna o valor dentro doOption, ou um valor padrão se forNone.let x: Option<i32> = None;
let result = x.unwrap_or(10); // 10 -
map_or(): Semelhante aounwrap_or(), mas funciona com uma função de transformação.let x = Some(5);
let result = x.map_or(0, |n| n * 2); // 10
O Operador ? com Option
O operador ? pode ser usado com Option para simplificar o tratamento de erros. Se o Option for None, ele retorna imediatamente.
fn dividir(a: i32, b: i32) -> Option<i32> {
if b == 0 {
return None; // Evitar divisão por zero
}
Some(a / b)
}
fn main() {
let resultado = dividir(10, 2)?;
println!("Resultado: {}", resultado); // 5
}
Se dividir(10, 0) fosse chamado, a função retornaria None, e o operador ? propagaria esse None para fora da função.
Conclusão
O Option é um dos tipos mais importantes em Rust, permitindo lidar com valores opcionais de forma segura, sem o risco de acessar valores nulos. Ele oferece uma variedade de métodos para manipular os valores de forma segura, tornando o código mais previsível e menos propenso a erros.