获取向量的最后一个元素并将其推送到同一向量

时间:2016-06-01 22:39:25

标签: vector rust

我想做什么:

enum Test {
    Value1,
    Value2,
    Value3
}

fn main() {
    let mut test_vec: Vec<Test> = Vec::new();
    test_vec.push(Test::Value2);

    if let Some(last) = test_vec.last() {
        test_vec.push(*last);
    }
    //Wanted output: vector with [Test::Value2, Test::Value2]
}

我了解当我致电last()时,它会返回Option<&Test> 所以它将借用test_vec直到if-let块结束。

我尝试了以下但没有成功:

if let Some(last) = test_vec.last().map(|v| v.clone()) {
    test_vec.push(*last);
}

//and

let last = test_vec.last().unwrap().clone();
test_vec.push(*last);

2 个答案:

答案 0 :(得分:6)

要解决借阅问题,您可以拨打Option::cloned,从Option<T>生成Option<&T>。为此,Test必须实施Clone。您可以使用Clone

Test实施derive
// To allow assert_eq, we also derive Debug and PartialEq
#[derive(Debug, PartialEq, Clone)]
enum Test {
    Value1,
    Value2,
    Value3
}

fn main() {
    let mut test_vec = Vec::new();
    test_vec.push(Test::Value2);

    if let Some(last) = test_vec.last().cloned() {
        test_vec.push(last);
    }

    assert_eq!(vec![Test::Value2, Test::Value2], test_vec);
}

答案 1 :(得分:3)

当试图找出借用检查者为什么抱怨时,识别所涉及的类型会很有用。

如果您输入:

let _: () = test_vec.last().map(|v| v.clone());

您收到的错误是抱怨()core::option::Option<&Test>类型不同。

发生了什么?非常简单地说,如果您克隆&Test,则会得到&Test,因此在.map(|v| v.clone())上调用Option<&Test>会得到Option<&Test>。显然,它仍然借用。

如果您输入以下内容,下次尝试时会出现同样的问题:

let _: () = test_vec.last().unwrap().clone();

您收到的错误是抱怨()&Test类型不同。

通过unwrap调用Option<&Test>,您会获得一个&Test,然后将其克隆到&Test

所以,问题是缺少解除引用。您需要提前取消引用,以避免在test_vec中借用Some(last)

if let Some(last) = test_vec.last().map(|v| (*v).clone()) {
    test_vec.push(last);
}

当然,这不起作用,因为Test没有实现clone。一旦修复(由#[derive(Clone)]),它就会编译。

由于从引用中克隆是如此常见的需求,Option(和Iterator)上有一个名为cloned的专用方法:

if let Some(last) = test_vec.last().cloned() {
    test_vec.push(last);
}