根据其最后一个元素将某物推入向量 [英] Pushing something into a vector depending on its last element

查看:59
本文介绍了根据其最后一个元素将某物推入向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获取向量的最后一个元素并使用它来确定要推入的下一个元素.这是一个如何不起作用的示例,但它显示了我想要实现的目标:

I would like to get the last element of a vector and use it to determine the next element to push in. Here's an example how it doesn't work, but it shows what I'm trying to achieve:

let mut vector: Vec<i32> = Vec::new();

if let Some(last_value) = vector.last() {
    vector.push(*last_value + 1);
}

我不能使用 push 而向量也是不可改变地借用的:

I can't use push while the vector is also borrowed immutably:

error[E0502]: cannot borrow `vector` as mutable because it is also borrowed as immutable
 --> src/main.rs:5:9
  |
4 |     if let Some(last_value) = vector.last() {
  |                               ------ immutable borrow occurs here
5 |         vector.push(*last_value + 1);
  |         ^^^^^^ mutable borrow occurs here
6 |     }
  |     - immutable borrow ends here

这样做的好方法是什么?

What would be a good way to do this?

推荐答案

After Non-Lexical Lifetimes

您的原始代码 工作为-在 Rust 2018 中,它启用了非词法生命周期:

fn main() {
    let mut vector: Vec<i32> = Vec::new();

    if let Some(last_value) = vector.last() {
        vector.push(*last_value + 1);
    }
}

借用检查器已得到改进,以实现 last_value 中的引用与推入新值所需的 vector 的可变借用不重叠.

The borrow checker has been improved to realize that the reference in last_value does not overlap with the mutable borrow of vector needed to push a new value in.

请参阅从 HashMap 或 Vec 返回引用会导致借用持续超出其所在的范围?借用检查器还不够智能来处理的情况(从 Rust 1.32 开始).

See Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in? for a similar case that the borrow checker is not yet smart enough to deal with (as of Rust 1.32).

vector.last() 的结果是一个 Option<&i32>.该值中的引用保持借用向量.在我们可以推送到它之前,我们需要摆脱对向量的所有引用.

The result of vector.last() is an Option<&i32>. The reference in that value keeps the vector borrowed. We need to get rid of all references into the vector before we can push to it.

如果您的向量包含Copy可用的值,请从向量中复制该值以更快地结束借用.

If your vector contains Copyable values, copy the value out of the vector to end the borrow sooner.

fn main() {
    let mut vector: Vec<i32> = Vec::new();

    if let Some(&last_value) = vector.last() {
        vector.push(last_value + 1);
    }
}

在这里,我使用了模式 Some(&last_value) 而不是 Some(last_value).这会解构引用并强制复制.如果您使用不能Copy的类型尝试此模式,您将收到编译器错误:

Here, I've used the pattern Some(&last_value) instead of Some(last_value). This destructures the reference and forces a copy. If you try this pattern with a type that isn't Copyable, you'll get a compiler error:

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:4:17
  |
4 |     if let Some(&last_value) = vector.last() {
  |                 ^----------
  |                 ||
  |                 |hint: to prevent move, use `ref last_value` or `ref mut last_value`
  |                 cannot move out of borrowed content

如果您的向量不包含 Copyable 类型,您可能需要先克隆该值:

If your vector does not contain Copyable types, you might want to clone the value first:

fn main() {
    let mut vector: Vec<String> = Vec::new();

    if let Some(last_value) = vector.last().cloned() {
        vector.push(last_value + "abc");
    }
}

或者你可以用另一种方式转换值,使得 .map() 调用返回一个不从向量中借用的值.

Or you can transform the value in another way such that the .map() call returns a value that doesn't borrow from the vector.

fn main() {
    let mut vector: Vec<String> = Vec::new();

    if let Some(last_value) = vector.last().map(|v| v.len().to_string()) {
        vector.push(last_value);
    }
}

这篇关于根据其最后一个元素将某物推入向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆