item_vec.last()
is an Option<&T>
.
item_vec.last().clone()
is another Option<&T>
. This actually performs a shallow copy of the reference. This means you haven't actually fixed anything!
Intuitively, this makes sense - cloning a pointer can return a value type to store directly on the stack, but a clone of an Option<&T>
can't clone the T
because it has nowhere to put it.
This works because an Option<T>
actually calls clone
on an &T
, so Option<&T>
calls clone
on an &&T
, which means the &self
parameter in the trait resolves to self = &T
. This means we use the impl
of Clone
for &T
:
impl<'a, T: ?Sized> Clone for &'a T {
/// Returns a shallow copy of the reference.
#[inline]
fn clone(&self) -> &'a T { *self }
}
*item_vec.last().clone().unwrap()
thus is still a borrow of the vector.
One can fix this in two basic ways. One is to use Option
's cloned
method, which clones the inner reference away:
item_vec.last().cloned().unwrap()
This is implemented as a map
on the internal data:
impl<'a, T: Clone> Option<&'a T> {
/// Maps an Option<&T> to an Option<T> by cloning the contents of the Option.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn cloned(self) -> Option<T> {
self.map(|t| t.clone())
}
}
The other option is to unwrap
and only then clone
the reference, to get a value out:
item_vec.last().unwrap().clone()
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…