Skip to main content

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, onde T é o tipo do valor.
  • None representa 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 o Option é Some ou None.

    let x = Some(5);
    assert!(x.is_some());
    assert!(!x.is_none());
  • map(): Transforma o valor dentro do Option se ele for Some.

    let x = Some(5);
    let y = x.map(|n| n * 2);
    println!("{:?}", y); // Some(10)
  • unwrap(): Obtém o valor dentro do Option, causando pânico se for None.

    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 um Option.

    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 do Option, ou um valor padrão se for None.

    let x: Option<i32> = None;
    let result = x.unwrap_or(10); // 10
  • map_or(): Semelhante ao unwrap_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.