// DOCS NAVIGATION
Option<T> e Result<T, E>_
SOURCE: content/docs/reference/04-avancado.md — 04 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 valorOption::None— não há valor
EN-US:
Option<T> represents a value that may or may not exist:
Option::Some(value)— there is a valueOption::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 valorResult::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 valueResult::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
}
}