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

时间:2015-08-09 19:10:34

标签: 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,
    }
}

我收到以下错误:

  

错误:无法移出借来的内容
  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,
    }
}

编译器不会抱怨借用。

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

1 个答案:

答案 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