El operador ?
En esta página
El operador ? es azúcar sintáctico para la propagación automática: si el valor
es Result::Ok(v), extrae v; si es Result::Err(e), retorna el error
inmediatamente al llamador. El efecto es el mismo que match + return, pero
sin el ruido visual.
El archivo a continuación compara la forma verbosa con la concisa y muestra que
? también funciona con T? (opcional):
? en Result y en Option: propagación limpia sin if/match manuales.
03-try-operator.zolo
// Feature: `?` operator — automatic propagation
// Syntax: `let x = expr?` (extracts Ok or returns Err)
// When to use: chain Result-returning calls without boilerplate.
use std::Result
fn divide(a: int, b: int) -> Result<int, str> {
if b == 0 {
return Result.Err("division by zero")
}
return Result.Ok(a / b)
}
// Without `?` — nested match, verbose:
fn compute_verbose(a: int, b: int, c: int) -> Result<int, str> {
let r1 = divide(a, b)
if r1.is_err() {
return r1
}
let x = r1.unwrap()
let r2 = divide(x, c)
if r2.is_err() {
return r2
}
return Result.Ok(r2.unwrap())
}
// With `?` — clean:
fn compute(a: int, b: int, c: int) -> Result<int, str> {
let x = divide(a, b)? // if Err, returns Err immediately
let y = divide(x, c)? // same here
return Result.Ok(y)
}
fn describe(r: Result<int, str>) {
match r {
Result::Ok(v) => print("ok: {v}"),
Result::Err(e) => print("error: {e}"),
}
}
describe(compute(100, 4, 5))
// expected: ok: 5
describe(compute(100, 0, 5))
// expected: error: division by zero
describe(compute(100, 4, 0))
// expected: error: division by zero
// Verbose and short forms produce the same result:
describe(compute_verbose(100, 4, 5)) // ok: 5
describe(compute_verbose(100, 0, 5)) // error: division by zero
// `?` also works with Option (T?). If None/nil, returns nil.
fn first(arr: [int]) -> int? {
if arr.len() == 0 {
return nil
}
return arr[0]
}
fn sum_firsts(a: [int], b: [int]) -> int? {
let x = first(a)?
let y = first(b)?
return x + y
}
print(sum_firsts([1, 2], [3, 4])) // 4
print(sum_firsts([], [3, 4])) // nil
print(sum_firsts([1], [])) // nil
La función que usa
?debe tener un tipo de retorno compatible:Result<_, E>paraResult, oT?para opcionales.
Desafío
Intenta llamar compute(100, 4, 0) y compute(0, 1, 1). ¿Qué paso de la
cadena dispara el error en cada caso? Cambia divide para retornar 0 en lugar
de Err cuando b == 0 y observa qué cambia.
Consulta también