如何从矢量克隆最后一个元素

  • 本文关键字:最后一个 元素 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,
    }
}

我得到以下错误:

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

编译器不会抱怨借用。

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

item_vec.last()Option<&T>

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

直观地说,这是有意义的——克隆一个指针可以返回一个值类型来直接存储在堆栈上,但是克隆一个Option<&T> 不能克隆T,因为它没有地方放它。

这可以工作,因为Option<T>实际上在&T上调用clone,所以Option<&T>&&T上调用clone,这意味着trait中的&self参数解析为self = &T。这意味着我们将Cloneimpl用于&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()仍然是vector的借位。

可以用两种基本方法解决这个问题。一种是使用Optioncloned方法,该方法克隆内部引用:

item_vec.last().cloned().unwrap()

这是在内部数据上实现的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())
    }
}

另一个选择是unwrap,只有,然后 clone的引用,得到一个值:

item_vec.last().unwrap().clone()

最新更新