我在使用Rust 2018时遇到了一个borrowchecker问题,无法找到解决方法。基本上,我有一个函数,它接受一个可变引用类型的vec,并将该相同的vec作为其执行的第一部分传递给另一个函数作为不可变引用类型。后一个函数返回一个新的拥有值 - 或者至少是我打算这样做的。对我来说,问题在于编译器似乎认为函数调用的不可变借用会持续到外部函数结束。
不幸的是,这不是简单地将括号放在周围就可以解决的问题(无论如何,因为我正在使用Rust 2018)。此外,虽然我发现了一些看起来涉及类似问题的SO问题(例如这个,这个,这个和这个),但我没有能够找到其他直接解决此问题的内容。关键是,大多数其他类似问题似乎要求返回类型为引用,或者仅在非词法生存期之前存在问题。
我在Rust Playground中创建了一个可执行的MVE,并在需要时添加了完整程序。我将代码放在下面供参考:
编译器产生的错误信息是:
看起来,根据错误消息,我觉得这两个函数指定的生命周期可能存在问题。我得承认,我加进去的生命周期基本上只是根据编译器和 Clippy 的建议放进去的,我不是完全理解它们。我能说的最好的是,编译器似乎认为在调用
我做错了什么呢?我要怎样让编译器满意呢?我猜这可能涉及指定另一个生命周期,但是尽管看了 The Book 和一些在线资源,我还是没有找到正确的方法。
不幸的是,这不是简单地将括号放在周围就可以解决的问题(无论如何,因为我正在使用Rust 2018)。此外,虽然我发现了一些看起来涉及类似问题的SO问题(例如这个,这个,这个和这个),但我没有能够找到其他直接解决此问题的内容。关键是,大多数其他类似问题似乎要求返回类型为引用,或者仅在非词法生存期之前存在问题。
我在Rust Playground中创建了一个可执行的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 和一些在线资源,我还是没有找到正确的方法。