SPECTRALANG_

// DOCS NAVIGATION

Option<T> e Result<T, E>_

SOURCE: content/docs/reference/04-avancado.md04 Avançado / 4. Option<T> e Result<T, E>

PT-BR:
Option<T> e Result<T, E> são os tipos centrais para lidar com ausência de valores e erros de forma segura, sem exceções.

EN-US:
Option<T> and Result<T, E> are the central types for handling absence of values and errors safely, without exceptions.

Option<T>

PT-BR:
Option<T> representa um valor que pode ou não existir:

  • Option::Some(valor) — há um valor
  • Option::None — não há valor

EN-US:
Option<T> represents a value that may or may not exist:

  • Option::Some(value) — there is a value
  • Option::None — there is no value
func dividir_seguro(a: int, b: int) returns Option<int> {
    if b == 0 {
        return Option::None
    }
    return Option::Some(a / b)
}

func obter_primeiro(arr: [int], n: int) returns Option<int> {
    if n == 0 {
        return Option::None
    }
    return Option::Some(arr[0])
}

public func main() {
    // Usando match / Using match
    let resultado = dividir_seguro(10, 2)
    match resultado {
        when Option::Some(v) then println(f"Resultado: {v}"),  // "Resultado: 5"
        when Option::None then println("Divisão por zero!")
    }

    // Usando if let / Using if let
    if let Option::Some(n) = dividir_seguro(10, 0) {
        println(f"Valor: {n}")
    } else {
        println("Sem resultado")
    // Imprime isso
    }

    // Funções da stdlib para Option / Stdlib functions for Option
    import std.option

    let opt = Option::Some(42)
    let tem = std.option.is_some(opt)
      // true
    let val = std.option.option_unwrap(opt)
// 42 (erro de runtime se None)
    let ou  = std.option.option_unwrap_or(Option::None, 0)
  // 0 (padrão)
}

Result<T, E>

PT-BR:
Result<T, E> representa uma operação que pode ter sucesso ou falhar:

  • Result::Ok(valor) — operação bem-sucedida com um valor
  • Result::Err(erro) — operação falhou com informação de erro

EN-US:
Result<T, E> represents an operation that can succeed or fail:

  • Result::Ok(value) — operation succeeded with a value
  • Result::Err(error) — operation failed with error information
import std.convert

func analisar_inteiro(s: string) returns Result<int, string> {
    let n = std.convert.string_to_int(s)
    if n == 0 && s != "0" {
        return Result::Err(f"'{s}' não é um inteiro válido")
    }
    return Result::Ok(n)
}

func dividir(a: int, b: int) returns Result<int, string> {
    if b == 0 {
        return Result::Err("divisão por zero")
    }
    return Result::Ok(a / b)
}

public func main() {
    // Correspondência exaustiva / Exhaustive matching
    match analisar_inteiro("42") {
        when Result::Ok(n) then println(f"Sucesso: {n}"),
        when Result::Err(msg) then println(f"Erro: {msg}")
    }

    match analisar_inteiro("abc") {
        when Result::Ok(n) then println(f"Sucesso: {n}"),
        when Result::Err(msg) then println(f"Erro: {msg}")    // Imprime isso
    }

    // Encadeamento de operações / Chaining operations
    if let Result::Ok(n) = analisar_inteiro("10") {
        if let Result::Ok(resultado) = dividir(n, 2) {
            println(f"10 / 2 = {resultado}")
    // 5
        }
    }

    // Funções da stdlib / Stdlib functions
    import std.result

    let r = Result::Ok(100)
    let ok     = std.result.is_ok(r)
               // true
    let val    = std.result.result_unwrap(r)
        // 100
    let padrao = std.result.result_unwrap_or(Result::Err("e"), 0)
 // 0
}

Convertendo entre Option e Result

// Option → Result
func opcao_para_resultado(opt: Option<int>, msg_erro: string) returns Result<int, string> {
    match opt {
        when Option::Some(v) then Result::Ok(v),
        when Option::None then Result::Err(msg_erro)
    }
}

// Result → Option (descartando o erro)
func resultado_para_opcao(res: Result<int, string>) returns Option<int> {
    match res {
        when Result::Ok(v) then Option::Some(v),
        when Result::Err(_) then Option::None
    }
}