在非词法生命周期之后
您的原始代码works as-is in Rust 2018,启用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 的可变借用不重叠。
请参阅Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in? 以了解借用检查器还不够智能以处理的类似情况(从 Rust 1.32 开始)。
在非词法生命周期之前
vector.last() 的结果是Option<&i32>。该值中的引用保留了借用的向量。我们需要先删除对向量的所有引用,然后才能推送到它。
如果您的向量包含Copyable 值,请将值从向量中复制出来以更快地结束借用。
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)。这解构引用并强制复制。如果您尝试使用不是 Copyable 的类型使用此模式,您将收到编译器错误:
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 类型,您可能需要先克隆该值:
fn main() {
let mut vector: Vec<String> = Vec::new();
if let Some(last_value) = vector.last().cloned() {
vector.push(last_value + "abc");
}
}
或者您可以以另一种方式转换该值,以便 .map() 调用返回一个不从向量借用的值。
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);
}
}