阅读“The Rust Programming Language”-“18. Patterns and Matching”部分,章节 "18.3. Pattern Syntax" .在本章的末尾,“@Bindings”部分介绍了一种方法来“创建一个保存值的变量,同时我们正在测试该值以查看它是否与模式匹配”。但是,我很难看出这比本章前面的“带有 Match Guards 的额外条件”一节中讨论的方法有什么值(value)。
例如,以下面“@Bindings”部分的代码示例为例,我相信我已经以两种方式实现了相同的逻辑,因此我没有看到“@Bindings”方法的值(value)。
enum Message {
Hello { id: i32},
}
fn main() {
let msg = Message::Hello { id: 5 };
// @ Binding Operator Example
match msg {
Message::Hello { id: idvar @ 3..=7 } => println!("Found an id in range: {}", idvar),
Message::Hello { id: 10..=12 } => println!("Found an id in another range"),
Message::Hello { id } => println!("Found some other id: {}", id),
}
// Conditional Match Guard Example
match msg {
Message::Hello { id: idvar } if (3..=7).contains(&idvar) => println!("Found an id of range: {}", idvar),
Message::Hello { id: idvar } if (idvar >= 10 && idvar <=12) => println!("Found an id in another range"),
Message::Hello { id: idvar } => println!("Found some other id: {}", idvar),
}
}
注意:我只是在比赛守卫中使用两种不同的方法来定义一个范围作为实验——与问题没有直接关系
我确信我遗漏了一些微妙的好处(书中提供的简化示例可能没有解决)。 @ 运算符绑定(bind)方法提供了哪些独特的好处,或者它只是一种替代方法?
最佳答案
主要区别在于详尽检查。匹配守卫无法在编译器中进行详尽检查,因此可能需要使用绑定(bind)可以避免的其他情况。这是一个例子:
let n = 5u8;
// this works: the compiler can tell that together, each arm covers all
// possible cases
match n {
value @ 0..=127 => println!("low: {}", n),
value @ 127..=255 => println!("high: {}", n),
}
// this doesn't work: match guards don't contribute to exhaustiveness
// checking, so the compiler isn't sure that all possible cases are covered
// and requires a default case (even though it's unreachable)
match n {
value if (0..=127).contains(&value) => println!("low: {}", n),
value if (127..=255).contains(&value) => println!("high: {}", n),
// uncommenting this line will allow it to compile
// _ => unreachable!()
}
关于rust - @ operator bindings over extra conditionals with match guards的好处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70489144/