Avoid additional validation when accessing the vector
How can I avoid additional validation when accessing 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);
}
There are 2 problems:
- I need to check with the operator
if let
... (but I know I don't need this) - I need
else panic
it because without it ittop_path
can be uninitialized (-> error).
Is it my fault or is it Rusta?
source to share
You can use a method Option::unwrap
that panics in the None
same way as an expression 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);
}
but in this case it would be even clearer to use a block while let
as you mentioned in your own answer.
source to share
In this case, you must use an iterator. It's just as efficient (maybe more) and shorter:
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);
}
}
In your example, Rust does not know that there is a relationship between is_empty
and pop
, so it must handle the failure case in pop
. The iterator provides a more recognizable interface to the vector and may not check for load outside of the bounds.
source to share