【发布时间】:2019-12-12 14:41:54
【问题描述】:
我在使用 Rust 2018 时遇到了一个借用检查器问题,我找不到解决方案。基本上,我有一个函数接受对 vec 的可变引用,并且在其执行的第一部分将相同的 vec 作为不可变引用传递给另一个函数。后一个函数返回一个新的拥有值——或者至少我打算这样做。我的问题是编译器似乎认为函数调用的不可变借用持续到外部函数结束。
不幸的是,这不是一个简单地通过在事物周围放置大括号就能解决的问题(无论如何都不应该这样,因为我使用的是 Rust 2018)。此外,虽然我发现了一些似乎涉及类似问题的 SO 问题(例如 this、this、this 和 this),但我还没有找到任何其他可以直接解决的问题这个问题。或者至少,我无法从中找出我应该做什么。至关重要的是,大多数其他类似问题似乎都涉及作为返回类型的引用,或者只是非词法生命周期之前的一个问题。
我在Rust Playground 和full program 中创建了一个可执行的MVE,以防万一。我把代码贴在下面,供参考:
// This function was blatantly borrowed from a Stack Overflow post
// but unfortunately I lost track of which one.
fn compute_mean_of_vec<'g, T>(input_vec: &'g [T]) -> T
where
T: Copy
+ num::Zero
+ std::ops::Add<T, Output = T>
+ std::ops::Div<T, Output = T>
+ num::FromPrimitive
+ std::iter::Sum<&'g T>,
{
let sum: T = input_vec.iter().sum();
sum / num::FromPrimitive::from_usize(input_vec.len()).unwrap()
}
fn normalise_cost_vec<'a, T>(cost_vec: &'a mut Vec<T>)
where
T: std::ops::SubAssign
+ Copy
+ num::traits::identities::Zero
+ std::ops::Div<Output = T>
+ num::traits::cast::FromPrimitive
+ std::iter::Sum<&'a T>,
{
let mean = compute_mean_of_vec(cost_vec);
for c in cost_vec.iter_mut() {
*c -= mean;
}
}
fn main() {
let mut my_vec = vec![5.0f32; 5];
normalise_cost_vec(&mut my_vec);
for e in my_vec.iter() {
println!("{}", e);
}
}
编译器产生的错误信息是:
error[E0502]: cannot borrow `*cost_vec` as mutable because it is also borrowed as immutable
--> src/main.rs:26:14
|
16 | fn normalise_cost_vec<'a, T>(cost_vec: &'a mut Vec<T>)
| -- lifetime `'a` defined here
...
25 | let mean = compute_mean_of_vec(cost_vec);
| -----------------------------
| | |
| | immutable borrow occurs here
| argument requires that `*cost_vec` is borrowed for `'a`
26 | for c in cost_vec.iter_mut() {
| ^^^^^^^^ mutable borrow occurs here
查看错误消息,在我看来,这两个函数上指定的生命周期可能存在一些问题。我不得不承认,我包含的那些几乎只是根据编译器和 Clippy 的建议放在那里的,我没有完全理解它们。据我所知,编译器以某种方式认为对compute_mean_of_vec 的调用中的不可变借用应该持续到对normalise_cost_vec 的调用的整个其余部分。
我做错了什么,如何让编译器满意?我想这与指定另一个生命周期有关,但尽管查看了 The Book 和许多在线资源,但我仍然无法找到正确的方法。
【问题讨论】:
标签: rust