Rust 在访问向量时避免可选的检查
访问Rust 在访问向量时避免可选的检查,rust,optional,Rust,Optional,访问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 l
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);
}
有两个问题:
else死机
,因为没有它,top\u路径
可能会被取消初始化(->错误)这是我的错误还是生锈了?在这种情况下,您应该使用迭代器。它同样有效(也许更有效),而且更短:
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
中处理故障情况。迭代器向向量公开了一个更具知识性的接口,可以避免检查是否超出引导范围。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);
}
这看起来好多了。你可以使用这个方法,它会像你的一样让你的感到恐慌。。。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);
}
但是在这种情况下,使用,而让
阻塞会更清楚,正如您在自己的回答中所提到的。如果您需要通过循环内的可变引用调用采用self
或stack
的方法,则这将不起作用。@mbrubeck-sure,但您不会弹出堆栈,因此,问题中的示例将不同。在问题的示例中,如果self.apply\u grammar
采用&mut self
,则while
或while let
循环将起作用,但for
循环将不起作用。(您可以使用std::mem::replace
解决此问题)注意:如果您不知道,这称为无可辩驳的模式。