如何从向量中克隆最后一个元素?

Yan*_*ang 3 rust

我正在尝试编写代码来获取某个向量的最后一个元素,并根据该元素执行不同的操作(包括向量的变异).

我试过这样的:

#[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,
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

错误:无法移出借来的内容
让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,
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器不会抱怨借用.

为什么我的代码无法编译?

Vee*_*rac 8

item_vec.last()是一个Option<&T>.

item_vec.last().clone()是另一个Option<&T>.这实际上执行了引用的浅表副本.这意味着你实际上没有修复任何东西!

直觉上,这是有道理的 - 克隆一个指针可以返回一个值类型直接存储在堆栈上,但是一个克隆Option<&T> 无法克隆T它,因为它无处可放.

这是因为Option<T>实际上调用clone了一个&T,所以Option<&T>调用clone一个&&T,这意味着特征中的&self参数解析为self = &T.这意味着我们使用implClone&T:

impl<'a, T: ?Sized> Clone for &'a T {
    /// Returns a shallow copy of the reference.
    #[inline]
    fn clone(&self) -> &'a T { *self }
}
Run Code Online (Sandbox Code Playgroud)

*item_vec.last().clone().unwrap() 因此仍然是向量的借用.

人们可以用两种基本方式解决这个问题.一种是使用Optioncloned方法,其中克隆的内参考远:

item_vec.last().cloned().unwrap()
Run Code Online (Sandbox Code Playgroud)

这是作为map内部数据实现的:

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())
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是unwrap,只有 clone参照,要得到一个值出来:

item_vec.last().unwrap().clone()
Run Code Online (Sandbox Code Playgroud)