enums - 两种类型的派送应该怎么做?
问题描述
在这段代码中:
impl Msg {
fn apply_to(&self, state: &mut State) {
match (self, state) {
(Msg::MsgA(m), State::StateOne(s)) => {
m.apply_to_state_one(s);
},
(Msg::MsgB(m), State::StateOne(s)) => {
m.apply_to_state_one(s);
},
// FIXME: can these two dispatches be made into one
(Msg::MsgC(m), State::StateOne(s)) => {
m.apply_to_common_state(&mut s.common);
},
(Msg::MsgC(m), State::StateTwo(s)) => {
m.apply_to_common_state(&mut s.common);
},
(Msg::MsgD(m), State::StateTwo(s)) => {
m.apply_to_state_two(s);
},
(_, _) => { // don't care
()
}
}
}
}
有没有吸引力的样板,更多的是在完整的操场上。
我希望每个Msg
都能够应用于 a StateOne
, aStateTwo
或其中之一(通过它们的公共字段,common
)。
Msg
s 在应用于他们没有实现的状态时应该出错。
我希望所有逻辑都在单个消息中,没有任何逻辑Msg
或State
s。
如何在 Rust 的类型系统中最好地表达这一点?
更新:我特别想知道我解决这个问题的一般方法是否适用于 Rust,或者如果消息或状态是泛型或dyn trait
对象,是否有更好的解决方案。
解决方案
您可以考虑使用结构解构来组合它们:
(Msg::MsgC(m), State::StateOne(StateOne {mut common, ..}))
| (Msg::MsgC(m), State::StateTwo(StateTwo {mut common, ..})) => {
m.apply_to_common_state(&mut common);
},
它不是最漂亮的,但是在or 模式稳定之后,它可能会减少到(Msg::MsgC(m), State::StateOne(StateOne {mut common, ..}) | State::StateTwo(StateTwo {mut common, ..}))
.
推荐阅读
- objective-c - 如何从静止图像(png)渲染固定长度的视频文件
- python - 将 numpy 1D 数组重塑为 3D 数组
- linux - 需要帮助编写 shell 脚本来检查文件是否存在?
- javascript - 在 Ag-grid 中手动打开/关闭排序箭头
- javascript - jQuery在DOM中为不同的父级输入下一个输入
- flutter - 无法完成 Flutter 安装
- c++ - 如何与数据库qt建立连接
- arrays - 在 presto 中格式化包含日期数据类型的未嵌套字段
- c++ - 元程序在运行时使用枚举值作为模板函数的模板参数
- sqlite - sqlite:夹具加载 null 而不是字符串 - NOT NULL 约束失败