Saltar al contenido

Resultado (std::Result)

En esta página

std::Result representa un éxito (Result.Ok(valor)) o un fallo (Result.Err(mensaje)). Las funciones que pueden fallar retornan un Result en lugar de lanzar excepciones — el llamador decide cómo reaccionar.

Ok y Err

Los dos constructores y los predicados is_ok / is_err:

Función divide que retorna Ok o Err según el divisor.

01-ok-and-err.zolo
Playground
// Feature: Result.Ok / Result.Err — the two variants of the type

// When to use: representing success or failure without using exceptions.


use std::Result

let ok = Result.Ok(42)
let err = Result.Err("failed")

// is_ok / is_err — quick checks.

print(ok.is_ok())  // expected: true

print(ok.is_err())  // expected: false

print(err.is_ok())  // expected: false

print(err.is_err())  // expected: true


// Function that returns a Result.

fn divide(a: int, b: int) -> Result<int, str> {
  if b == 0 {
    return Result.Err("division by zero")
  }
  return Result.Ok(a / b)
}

let r1 = divide(10, 2)
let r2 = divide(10, 0)
print(r1.is_ok())  // expected: true

print(r2.is_err())  // expected: true

Unwrap

unwrap() extrae el valor de un Ok — entra en pánico si es Err. Usa unwrap_or(default) para proporcionar un fallback seguro:

unwrap_or nunca entra en pánico; unwrap_err extrae el mensaje de error.

02-unwrap.zolo
Playground
// Feature: .unwrap / .unwrap_or / .unwrap_err — extracting the value

// When to use: pulling the inner value; unwrap_or avoids panic on Err.


use std::Result

let ok = Result.Ok(42)
let err = Result.Err("oops")

// unwrap — returns the value; PANICS on Err.

print(ok.unwrap())  // expected: 42


// unwrap_or — safe default when Err.

print(err.unwrap_or(0))  // expected: 0

print(ok.unwrap_or(999))  // expected: 42


// unwrap_err — returns the error; PANICS on Ok.

print(err.unwrap_err())  // expected: oops


// Safe pattern: test first.

fn show(r: Result<int, str>) {
  if r.is_ok() {
    print("ok: {r.unwrap()}")
  } else {
    print("err: {r.unwrap_err()}")
  }
}

show(Result.Ok(10))  // expected: ok: 10

show(Result.Err("failure"))  // expected: err: failure

Map

map transforma el valor interno de un Ok sin salir del Result. Un Err pasa sin ser tocado. map_err hace lo mismo para el lado del error:

Encadenamiento de map para múltiples transformaciones.

03-map.zolo
Playground
// Feature: Result.map / Result.map_err — transform within a Result

// When to use: applying a transformation to the value without unwrapping.


use std::Result

let ok = Result.Ok(10)
let err = Result.Err("failure")

// map — transforms the inner value when Ok; passes Err through unchanged.

let doubled = ok.map(|x| x * 2)
print(doubled.unwrap())  // expected: 20


let still_err = err.map(|x| x * 2)
print(still_err.is_err())  // expected: true

print(still_err.unwrap_err())  // expected: failure


// map_err — transforms the error when Err; passes Ok through unchanged.

let prefixed = err.map_err(|e| "ERROR: " + e)
print(prefixed.unwrap_err())  // expected: ERROR: failure


let ok2 = ok.map_err(|e| "never")
print(ok2.unwrap())  // expected: 10


// Chain map for multiple transformations.

let r = Result.Ok(5)
let r2 = r.map(|x| x + 1)
let r3 = r2.map(|x| x * 10)
print(r3.unwrap())  // expected: 60

And Then

and_then encadena operaciones que ellas mismas retornan un Result. El primer Err interrumpe la cadena y se propaga:

Dos pasos que pueden fallar; and_then elimina la verificación manual.

04-and-then.zolo
Playground
// Feature: Result.and_then — chain operations that return a Result

// When to use: pipelines with multiple failing steps; each callback

// returns a fresh Result.


use std::Result

fn parse_int(s: str) -> Result<int, str> {
  if s == "1" { return Result.Ok(1) }
  if s == "2" { return Result.Ok(2) }
  if s == "3" { return Result.Ok(3) }
  return Result.Err("parse error: {s}")
}

fn double_if_even(n: int) -> Result<int, str> {
  if n % 2 == 0 {
    return Result.Ok(n * 2)
  }
  return Result.Err("not even: {n}")
}

// Happy path — all Ok.

let r1 = parse_int("2").and_then(double_if_even)
print(r1.is_ok())  // expected: true

print(r1.unwrap())  // expected: 4


// Failure in the 1st step — Err propagates.

let r2 = parse_int("z").and_then(double_if_even)
print(r2.is_err())  // expected: true


// Failure in the 2nd step.

let r3 = parse_int("1").and_then(double_if_even)
print(r3.is_err())  // expected: true

print(r3.unwrap_err())  // expected: not even: 1

El Operador ?

? tras una expresión Result extrae el Ok o retorna inmediatamente el Err al llamador — equivalente a if is_err { return } sin el ruido:

add con ? vs. add_v1 sin ? — idénticos en comportamiento, diferentes en claridad.

05-try-operator.zolo
Playground
// Feature: The `?` operator — propagates Err automatically

// When to use: clean code in pipelines; equivalent to if-let-Err-return.


use std::Result

fn parse_int(s: str) -> Result<int, str> {
  if s == "10" { return Result.Ok(10) }
  if s == "5" { return Result.Ok(5) }
  return Result.Err("parse: {s}")
}

// Without `?`: every call needs to be checked manually.

fn add_v1(a: str, b: str) -> Result<int, str> {
  let ra = parse_int(a)
  if ra.is_err() { return ra }
  let rb = parse_int(b)
  if rb.is_err() { return rb }
  return Result.Ok(ra.unwrap() + rb.unwrap())
}

// With `?`: each `?` extracts the Ok or returns the Err immediately.

fn add(a: str, b: str) -> Result<int, str> {
  let x = parse_int(a)?
  let y = parse_int(b)?
  return Result.Ok(x + y)
}

// Happy path.

let r1 = add("10", "5")
print(r1.unwrap())  // expected: 15


// Failure — first Err propagates.

let r2 = add("oops", "5")
print(r2.is_err())  // expected: true

print(r2.unwrap_err())  // expected: parse: oops


// Failure on the second call.

let r3 = add("10", "xyz")
print(r3.unwrap_err())  // expected: parse: xyz


// Both versions are equivalent.

print(add_v1("10", "5").unwrap())  // expected: 15

Desafío

Escribe una función sqrt_positive(n: int) -> Result<float, str> que retorne Err cuando n < 0 y Ok(sqrt(n)) en caso contrario. Luego compónla con and_then para calcular la suma de dos raíces cuadradas.

Consulta también

Buscar en Zolo

9 resultados

enespt-br