Accessing the last element of a Vec or a slice
39,662
Solution 1
And just after posting the question, the answer appears to be obvious:
fn top (&mut self) -> Option<&f64> {
match self.len() {
0 => None,
n => Some(&self[n-1])
}
}
I.e. the usize
was never the problem - the return type of top()
was.
Solution 2
You can use slice::last
:
fn top(&mut self) -> Option<f64> {
self.last().copied()
}
Option::copied
(and Option::cloned
) can be used to convert from an Option<&f64>
to an Option<f64>
, matching the desired function signature.
You can also remove the mut
from both the implementation and the trait definition.
Author by
user3518901
Updated on March 25, 2020Comments
-
user3518901 about 4 years
I have some code that looks like this:
trait Stack { fn top(&mut self) -> Option<f64>; } impl Stack for Vec<f64> { fn top(&mut self) -> Option<f64> { match self.pop() { None => None, Some(v) => { self.push(v); Some(v) } } } } fn main() { let mut stack: Vec<f64> = Vec::new(); stack.push(5.3); stack.push(2.3); stack.push(1.3); match stack.top() { Some(v) => println!("Top of the stack: {}", v), None => println!("The stack is empty"), } }
Right now, the
top()
method is modifyingself
, but I think that this should not be necessary. The obvious way to do it didn't really work:fn top(&mut self) -> Option<f64> { match self.len() { 0 => None, n => self[n - 1], } }
I've toyed around a bit with converting
usize
toi32
and back, but none of what I'm writing looks as short and readable as I think it should. -
U007D over 4 years
f64
isCopy
, so the&
's in the return type and then
arm of thematch
are not necessary, either. -
Scott Fraley almost 2 yearsSure wish there was an example of how to use this in context.