如何在Rust中构造状态对象?

问题描述

我有一个具有十几个或更多状态字段的应用。

struct State {
    a: u8,b: u16,c: u32,d: u64,...
}

其中大多数仅在某些状态下适用,尽管某些状态可能会全部出现:

struct StateOne {
    a: u8,...
}

struct StateTwo {
    a: u8,...
}

struct StateThree {
    a: u8,...
}

struct StateFour ...

通过尝试,我已经陷入困境:

enum State {
    StateOne { a: u8,... },StateTwo { a: u8,StateThree { a: u8,...
}

问题与必须手动将impl State { ...中的N种不同方法分配给M种不同状态有关。将来使用Enum Variant类型可能是可行的。

还有一个问题,状态转换方法必须返回状态,以防它们需要构造新的枚举变量。对于他们来说,最好接受&mut State(或&mut self)参数。

(我需要通过将消息应用于状态来建立新状态。我希望能够指定特定消息仅适用于特定状态。)

我已阅读:https://blog.yoshuawuyts.com/state-machines/#state-machines-in-rust-today,但99%的消息仅使当前状态的值发生变化。状态发生变化是非常特殊的。该文章的重点是状态更改是重要的事情。

我接下来很想创建一个SuperState结构:

struct SuperState {
    a: u8,b: Option<u16>,c: Option<u32>,d: Option<u64>,...
}

enum State {
    One,Two,Three,...
    Bad,}

impl SuperState {
    pub fn state_flag(&self) -> State {
        match (self.b,self.c,self.d) {
            (Some(b),None,None) => State::One,(None,Some(c),None) => State::Two,Some(d)) => State::Three,...
            _ => State::Bad,}
}

在这里,我将需要在运行时强制执行不变式,与具有严格字段集的枚举相比,这看起来不太好。

这值得一试吗,还是这里也有明显的问题?

还有其他更好的状态模式吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)