我如何说服生锈编译器内部match
表达式在这里很好,因为外部match
已经限制了可能的类型?
enum Op {
LoadX,
LoadY,
Add,
}
fn test(o: Op) {
match o {
Op::LoadX | Op::LoadY => {
// do something common with them for code reuse:
print!("Loading ");
// do something specific to each case:
match o {
// now I know that `o` can only be LoadX | LoadY,
// but how to persuade the compiler?
Op::LoadX => print!("x"), /* LoadX specific */
Op::LoadY => print!("y"), /* LoadY specific */
_ => panic!("shouldn't happen!"),
}
println!("...");
}
Op::Add => println!("Adding"),
}
}
fn main() {
test(Op::LoadX);
test(Op::LoadY);
test(Op::Add);
}
我尝试了两种方法,但似乎都起作用。
命名为or-pattern,然后使用该名称匹配:
match o { load@(Op::LoadX | Op::LoadY) => { // ... match load { // ... } }
那不是有效的生锈语法。
名称并绑定每个构造函数:
match o { load@Op::LoadX | load@Op::LoadY => { // ... match load { //... } }
仍然无法满足详尽的检查,因此会有相同的错误消息:
error[E0004]: non-exhaustive patterns: `Add` not covered --> src/main.rs:14:19 | 14 | match load { | ^ pattern `Add` not covered
是否有任何解决此问题的惯用方法,或者我应该在整个地方放置panic!("shouldn't happen")
或重组代码?
Rust Playground链接
你不能。从概念上讲,没有什么可以阻止您在外部匹配和内部匹配之间进行o = Op::Add
。变体完全有可能在两场比赛之间进行更改。
我可能会遵循Stargateur的代码,但是如果您不想重组枚举,请记住,Rust中有多种抽象技术。例如, functions 非常适合重复使用代码, CLOSURES (或特征(非常适合自定义逻辑。
enum Op {
LoadX,
LoadY,
Add,
}
fn load<R>(f: impl FnOnce() -> R) {
print!("Loading ");
f();
println!("...");
}
fn test(o: Op) {
match o {
Op::LoadX => load(|| print!("x")),
Op::LoadY => load(|| print!("y")),
Op::Add => println!("Adding"),
}
}
fn main() {
test(Op::LoadX);
test(Op::LoadY);
test(Op::Add);
}
我应该只放
panic!("shouldn't happen")
您应该使用unreachable!
而不是panic!
,因为它对程序员更正确。
我认为您只需要重构代码,显然LoadX
和LoadY
非常接近。因此,我认为您应该创建第二个枚举来重组它们:
enum Op {
Load(State),
Add,
}
enum State {
X,
Y,
}
fn test(o: Op) {
match o {
Op::Load(state) => {
// do something common with them for code reuse
print!("Loading ");
// do something specific to each case:
match state {
State::X => print!("x"),
State::Y => print!("y"),
}
println!("...");
}
Op::Add => println!("Adding"),
}
}
fn main() {
test(Op::Load(State::X));
test(Op::Load(State::Y));
test(Op::Add);
}
这对我来说更有意义。我认为这是表达您想要的更好的方法。