根据其最后一个元素将某物推入向量 [英] Pushing something into a vector depending on its last element
问题描述
我想获取向量的最后一个元素并使用它来确定要推入的下一个元素.这是一个如何不起作用的示例,但它显示了我想要实现的目标:
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 Copy
able 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 Copy
able, 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
如果您的向量不包含 Copy
able 类型,您可能需要先克隆该值:
If your vector does not contain Copy
able 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屋!