我正在尝试编写代码来获取某个向量的最后一个元素,并根据该元素执行不同的操作(包括向量的变异)。
我试过这样:
#[derive(Clone, PartialEq)]
enum ParseItem {
Start,
End,
}
let mut item_vec = vec![ParseItem::End];
loop {
let last_item = *item_vec.last().clone().unwrap();
match last_item {
ParseItem::End => item_vec.push(ParseItem::Start),
_ => break,
}
}
我收到以下错误:
错误:无法移出借来的内容
let last_item = * item_vec.last()。clone()。unwrap();
我想通过克隆item_vec.last()
,所有权问题就会得到解决,但似乎没有。
如果我用这样的整数向量尝试相同的事情:
let mut int_vec = vec![0];
loop {
let last_int = *int_vec.last().clone().unwrap();
match last_int {
0 => int_vec.push(1),
_ => break,
}
}
编译器不会抱怨借用。
为什么我的代码无法编译?
答案 0 :(得分:8)
item_vec.last()
是Option<&T>
。
item_vec.last().clone()
是另一个Option<&T>
。这实际上执行了引用的浅副本。这意味着您实际上没有修复任何东西!
直观地说,这是有道理的 - 克隆指针可以返回一个值类型直接存储在堆栈上,但Option<&T>
的克隆不能克隆{{1}因为无处可去。
这是有效的,因为T
实际上会在Option<T>
上调用clone
,因此&T
会在Option<&T>
上调用clone
,这意味着特征中的&&T
参数解析为&self
。这意味着我们使用the impl
of Clone
for &T
:
self = &T
impl<'a, T: ?Sized> Clone for &'a T {
/// Returns a shallow copy of the reference.
#[inline]
fn clone(&self) -> &'a T { *self }
}
因此仍然是向量的借用。
可以通过两种基本方式解决这个问题。一种是使用Option
's cloned
method,它克隆内部参考:
*item_vec.last().clone().unwrap()
This is implemented as a map
on the internal data:
item_vec.last().cloned().unwrap()
另一个选项是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())
}
}
,只有然后 unwrap
引用,以获取值:
clone