Pular para o conteúdo

Guia 28 de 53

Estados e eventos tipados

Eventos tipados e testemunhos de estado que restringem transições.

Nesta página

Eventos tipados e testemunhos de estado que restringem transições.

Eventos tipados e dados de estado

Uma máquina tipada possui seus enums State e Event. Padrões de transição vinculam dados do evento e estado apenas nessa transição. Dados iniciais executam uma vez por instância. send retorna false quando nenhuma transição se aplica; can_send verifica padrões sem executar guards ou ações.

Pratique na By Example · Programa fonte

// 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 cria uma máquina com ownership e testemunho do estado. send a consome e retorna o tipo do estado destino; uma falha de guard devolve a máquina e o evento originais. Funções podem exigir Order<.Paid>. erase_state devolve uma máquina dinâmica quando a checagem estática não é mais necessária.

Pratique na By Example · Programa fonte

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") }
    }
}

Continue aprendendo

Documentação · Pratique na By Example

DOCS / OPINIÃO

Esta página deixou alguma pergunta?

Conte onde a explicação perdeu você. A documentação também faz parte da experiência da linguagem.

Índice global

Encontre seu caminho pela Zolo

Experimente uma ideia

Comece por aqui

9 resultados

9 resultados

enespt-br