Opcionais
Nesta página
Quando um valor pode simplesmente não existir — e isso não é uma falha —
use o tipo opcional T?. O tipo aceita o valor nil (ausente) ou um valor do
tipo T (presente). Não existe Option.Some / Option.None em Zolo: a
presença é representada diretamente pelo valor.
T?, nil, ?? (coalescing), ?. (encadeamento seguro), if let como instrução e como expressão.
05-optionals.zolo
// Feature: Optionals — `T?`, `nil`, `??`, `?.`, `if let`
// Syntax: type `T?`, value `nil` or `T`, operators `??` and `?.`
// When to use: missing value that is NOT an error (e.g., lookup miss).
// -- Optional type ---------------------------------------------
let name: str? = nil
let age: int? = 42
print(name) // nil
print(age) // 42
// -- ?? — null coalescing (default) ---------------------------
let display_name = name ?? "Anonymous"
let display_age = age ?? 0
print("{display_name}, {display_age}")
// expected: Anonymous, 42
// -- ?. — optional chaining (safe access) ---------------------
struct Address {
city: str,
zip: str,
}
struct User {
name: str,
address: Address,
}
let u = User { name: "Alice", address: Address { city: "Porto", zip: "01000" } }
let city = u?.address?.city ?? "Unknown"
print(city)
// expected: Porto
// -- if let — unwraps if non-nil ------------------------------
let v: int? = 42
if let x = v {
print("got {x}")
} else {
print("empty")
}
// expected: got 42
let none: int? = nil
if let x = none {
print("got {x}")
} else {
print("empty")
}
// expected: empty
// -- if let as expression -------------------------------------
let doubled = if let x = v { x * 2 } else { 0 }
print(doubled) // 84
// -- Function returning an optional ---------------------------
fn find(id: int) -> str? {
if id == 1 { return "Alice" }
if id == 2 { return "Bob" }
return nil
}
print(find(1) ?? "not found") // Alice
print(find(3) ?? "not found") // not found
// -- Chaining ?? with multiple defaults -----------------------
let a: str? = nil
let b: str? = nil
let c: str? = "value C"
print(a ?? b ?? c ?? "fallback") // value C
Os três operadores principais:
??devolve o lado direito quando o lado esquerdo fornil— encadeável (a ?? b ?? c).?.acessa um campo ou chama um método; se o receptor fornil, o resultado inteiro se tornanilem vez de panicar.if let x = opcional { ... }desempacota o valor; o blocoelsecobre o casonil.
Use
T?+??para ausências esperadas (busca que pode não achar nada). UseResult<T, E>quando a ausência carrega informação de erro.
Desafio
Adicione uma quarta chamada find(4) ?? "not found" ao exemplo. Em seguida,
crie uma função find_upper(id: int) -> str? que use ?. para chamar
.to_upper() no resultado de find — o que acontece para id == 99?
Veja também