访问Vec
时如何避免可选检查?
while !self.stack.is_empty() {
let top_path;
if let Some(top) = self.stack.last() {
top_path = top.to_vec();
} else {
panic!("error (but can't happen, becouse the stack can't be empty becouse of the while loop)");
}
self.stack.pop();
self.apply_grammar(top_path);
}
有两个问题:
if let
...声明(但我知道我不需要它)else panic
,因为没有它top_path
可能未初始化( - >错误)。是我的错误还是Rust?
答案 0 :(得分:6)
irc帮助我得到了以下答案:
while let Some(top) = self.stack.pop() {
let top_path = top.to_vec();
let mut is_terminal = self.tree.root.is_terminal( top.to_vec() );
self.apply_grammar(top_path);
}
这看起来很多更好。 thx< 3
答案 1 :(得分:2)
您可以使用Option::unwrap
方法,它会像None
表达式一样在if let ... else
上发生恐慌:
while !self.stack.is_empty() {
let top = self.stack.last().unwrap();
let top_path = top.to_vec();
self.stack.pop();
self.apply_grammar(top_path);
}
但在这种情况下,如您在自己的回答中提到的那样使用while let
块会更清楚。
答案 2 :(得分:1)
在这种情况下,您应该使用迭代器。它同样有效(可能更多),而且更短:
fn main() {
let stack = vec![1,2,3,4,5,6];
// Consume the stack, pop from the beginning
for i in stack {
println!("{}", i);
}
let stack = vec![1,2,3,4,5,6];
// Consume the stack, pop from the end
for i in stack.into_iter().rev() {
println!("{}", i);
}
let stack = vec![1,2,3,4,5,6];
// Don't consume the stack, read from the beginning
for i in &stack {
println!("{}", i);
}
// Don't consume the stack, read from the end
for i in stack.iter().rev() {
println!("{}", i);
}
}
在您的示例中,Rust不知道is_empty
和pop
之间存在任何关联,因此它必须处理pop
中的失败案例。迭代器为向量公开了一个更加知识化的接口,并且可以避免检查越界以进行引导。