rust - Get the last element of a vector and push it to the same vector -
what trying do:
enum test { value1, value2, value3 } fn main() { let mut test_vec: vec<test> = vec::new(); test_vec.push(test::value2); if let some(last) = test_vec.last() { test_vec.push(*last); } //wanted output: vector [test::value2, test::value2] }
i understand when call last()
, return option<&test>
borrow test_vec
till end of if-let block.
i tried following without success:
if let some(last) = test_vec.last().map(|v| v.clone()) { test_vec.push(*last); } //and let last = test_vec.last().unwrap().clone(); test_vec.push(*last);
when trying figure out why borrow checker complains can useful identify types involved.
if type out:
let _: () = test_vec.last().map(|v| v.clone());
you error complaining ()
, core::option::option<&test>
not same type.
what's going on? put, if clone &test
&test
, calling .map(|v| v.clone())
on option<&test>
gives option<&test>
. obviously, still borrows.
the same problem occurs next attempt, if type out:
let _: () = test_vec.last().unwrap().clone();
you error complaining ()
, &test
not same type.
by calling unwrap
on option<&test>
&test
cloned &test
.
so, problem lack of dereferencing. need dereference earlier, avoid borrowing test_vec
in some(last)
:
if let some(last) = test_vec.last().map(|v| (*v).clone()) { test_vec.push(last); }
of course, not work because test
not implement clone
. once fixed (by #[derive(clone)]
), compiles.
since cloning references such common need, there dedicated method on option
(and iterator
) called cloned
:
if let some(last) = test_vec.last().cloned() { test_vec.push(last); }