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 }) // trueMá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¶
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.