Saltar al contenido

Guía 28 de 53

Estados y eventos tipados

Eventos tipados y testigos de estado que restringen transiciones.

En esta página

Eventos tipados y testigos de estado que restringen transiciones.

Eventos tipados y datos de estado

Una máquina tipada posee sus enums State y Event. Los patrones de transición enlazan datos del evento y estado solo en esa transición. Los datos iniciales se evalúan una vez por instancia. send devuelve false si no hay transición; can_send comprueba patrones sin ejecutar guards ni acciones.

Practica en By Example · Programa fuente

// Typed catalogs make states and events ordinary nominal enum values.
machine Loader {
    state Idle, Ready(value: int)
    event Loaded(value: int), Reset
    initial Idle

    Idle -> Ready(value) on Loaded(value) if value > 0
    Ready(previous) -> Idle on Reset
}

let loader = Loader.new()
print(loader.can_send(Loader::Event::Loaded(-1))) // true: structural applicability only
print(loader.send(Loader::Event::Loaded(-1)))     // false: the guard is checked by send
print(loader.send(Loader::Event::Loaded(7)))      // true
if let Loader::State::Ready(value) = loader.state { print(value) } // 7
print(loader.send(Loader::Event::Loaded(8)))      // false: no transition from Ready
print(loader.send(Loader::Event::Reset))         // true
print(match loader.state { Loader::State::Idle => true, Loader::State::Ready(_) => false })       // true

Máquinas indexadas por estado

new_static crea una máquina con propiedad y testigo de estado. send la consume y devuelve el tipo del estado destino; un guard fallido devuelve la máquina y el evento originales. Las funciones pueden exigir Order<.Paid>. erase_state devuelve una máquina dinámica cuando ya no necesitas comprobación estática.

Practica en By Example · Programa fuente

machine Order {
    state Draft, Paid, Shipped
    event Pay, Ship
    initial Draft
    Draft -> Paid on Pay
    Paid -> Shipped on Ship
}

fn ship(sink order: Order<.Paid>) -> Order<.Shipped> =
    order.send(Order.Event.Ship)

let paid = Order.new_static().send(Order.Event.Pay)
let shipped = ship(sink paid)
let ordinary = shipped.erase_state()
match ordinary.state {
    .Shipped => print("shipped"),
    _ => assert(false)
}

// A guarded transition returns the original machine and event on failure.
machine Door {
    state Closed, Open
    event Unlock
    initial Closed
    Closed -> Open on Unlock if false
}
match Door.new_static().send(Door.Event.Unlock) {
    .Ok(open) => { let ordinary = open.erase_state(); assert(false) },
    .Err({ machine: closed, event: retry }) => {
        let ordinary = closed.erase_state()
        match retry { .Unlock => print("closed") }
    }
}

Sigue aprendiendo

Documentación · Practica en By Example

DOCS / OPINIÓN

¿Esta página dejó alguna pregunta?

Cuéntanos dónde te perdió la explicación. La documentación también forma parte de la experiencia del lenguaje.

Índice global

Encuentra tu camino por Zolo

Prueba una idea

Empieza aquí

9 resultados

9 resultados

enespt-br