根据最后一个元素将某物推入向量中
Pushing something into a vector depending on its last element
我想获取向量的最后一个元素,并用它来确定要推入的下一个元素。这是一个它如何不起作用的示例,但它显示了我正在努力实现的目标:
let mut vector: Vec<i32> = Vec::new();
if let Some(last_value) = vector.last() {
vector.push(*last_value + 1);
}
我不能使用push
,而向量也是不可变地借用的:
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
执行此操作的好方法是什么?
非词法生命周期后
你的原码works as-is in Rust 2018, which enables non-lexical-lifetimes:
fn main() {
let mut vector: Vec<i32> = Vec::new();
if let Some(last_value) = vector.last() {
vector.push(*last_value + 1);
}
}
借用检查器已得到改进,以实现 last_value
中的引用不与推入新值所需的 vector
的可变借用重叠。
请参阅 了解借用检查器还不够智能以处理的类似情况(从 Rust 1.32 开始)。
在非词法生命周期之前
vector.last()
的结果是 Option<&i32>
。该值中的引用保留了借用的向量。在推送到向量之前,我们需要删除对向量的所有引用。
如果您的向量包含 Copy
可用值,请将值复制出向量以尽快结束借用。
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
无法使用的类型尝试此模式,您将收到编译器错误:
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 类型,您可能需要先克隆该值:
fn main() {
let mut vector: Vec<String> = Vec::new();
if let Some(last_value) = vector.last().cloned() {
vector.push(last_value + "abc");
}
}
或者您可以用另一种方式转换值,这样 .map()
调用 returns 一个不从向量借用的值。
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);
}
}
我想获取向量的最后一个元素,并用它来确定要推入的下一个元素。这是一个它如何不起作用的示例,但它显示了我正在努力实现的目标:
let mut vector: Vec<i32> = Vec::new();
if let Some(last_value) = vector.last() {
vector.push(*last_value + 1);
}
我不能使用push
,而向量也是不可变地借用的:
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
执行此操作的好方法是什么?
非词法生命周期后
你的原码works as-is in Rust 2018, which enables non-lexical-lifetimes:
fn main() {
let mut vector: Vec<i32> = Vec::new();
if let Some(last_value) = vector.last() {
vector.push(*last_value + 1);
}
}
借用检查器已得到改进,以实现 last_value
中的引用不与推入新值所需的 vector
的可变借用重叠。
请参阅
在非词法生命周期之前
vector.last()
的结果是 Option<&i32>
。该值中的引用保留了借用的向量。在推送到向量之前,我们需要删除对向量的所有引用。
如果您的向量包含 Copy
可用值,请将值复制出向量以尽快结束借用。
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
无法使用的类型尝试此模式,您将收到编译器错误:
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 类型,您可能需要先克隆该值:
fn main() {
let mut vector: Vec<String> = Vec::new();
if let Some(last_value) = vector.last().cloned() {
vector.push(last_value + "abc");
}
}
或者您可以用另一种方式转换值,这样 .map()
调用 returns 一个不从向量借用的值。
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);
}
}