【发布时间】:2017-07-16 17:16:52
【问题描述】:
假设我们有一个如下所示的枚举:
enum MyEnum {
Field1,
Field2 {x: f64, y: f64},
/* Maybe some other fields */
MyString(String),
}
现在我创建了这个枚举子类型 MyString 的实例,经过一些操作后,我想改变它。例如:
fn main() {
let mut my_enum = MyEnum::MyString("Hello, world".to_string());
/* Some actions */
// Mutating the string
match my_enum {
MyEnum::MyString(ref mut content) => {
content.push('!');
},
_ => {}
}
// Printing the string
match my_enum {
MyEnum::MyString(content) => {
println!("{}", content);
},
_ => {}
}
}
但是,当我们从上下文中确切地知道my_enum 可以仅 MyString 时,以这种方式进行匹配非常麻烦。我宁愿写这样的东西(不是正确的 Rust 语法):
my_enum@MyString.push('!');
println!("{}", my_enum@MyString);
如果,假设my_enum 是Field2 的子类型,那么要变异x:
my_enum@Field2.x += 1.0;
我可以这样做吗?我强烈认为答案是“否”,因为如果我从上面的匹配项中删除 _ => {},类型检查器就会开始抱怨非详尽的模式匹配:
patterns `Field1` and `Field2` not covered
尽管可以推断my_enum 只能是MyString。 “推断”是指编译器可以跟踪MyEnum 类型的所有变量,它们可以准确包含哪些值的子类型。
我在更大的代码中找到了一个地方,这可能很方便,但我想我可以用其他方式重写它。但是,我认为编译器可能会更聪明,并且至少可以理解在这种情况下,MyEnum::MyString 模式是详尽无遗的。如果上面问题的答案真的是“否”,我怀疑,如果这个问题在 Rust 开发人员之间讨论过(可能是一个 RFCS 链接?)以及是否值得提出功能请求,我很感兴趣。
【问题讨论】:
-
if let MyEnum::MyString(ref mut content) = my_enum { content.push('!'); }
标签: enums rust pattern-matching