我在使用 Rust 2018 时遇到了借用检查器问题,但找不到解决方案。基本上,我有一个函数接受对 vec 的可变引用,并且在其执行的第一部分将相同的 vec 作为不可变引用传递到另一个函数中。后一个函数返回一个新的拥有值 - 或者至少我打算这样做。对我来说,问题是编译器似乎认为函数调用的不可变借用持续到外部函数结束。
不幸的是,这不是一个简单地通过用大括号括起来就能解决的问题(无论如何都不应该这样,因为我使用的是 Rust 2018)。此外,虽然我发现了许多似乎涉及类似问题的问题(例如this、this、this和this),但我无法找到任何其他直接解决此问题的内容。或者至少,我无法从中弄清楚我应该做什么。至关重要的是,大多数其他类似问题要么似乎涉及引用作为返回类型,要么只是非词汇生命周期之前的问题。
我在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);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器产生的错误消息是:
// 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);
}
}
Run Code Online (Sandbox Code Playgroud)
查看错误消息,在我看来,这两个函数指定的生命周期可能存在一些问题。我必须承认,我包含的内容几乎只是根据编译器和 Clippy 的建议放在那里,我并不完全理解它们。据我所知,编译器以某种方式认为调用中的不可变借用compute_mean_of_vec
应该持续到调用的整个剩余部分normalise_cost_vec
。
我做错了什么,怎样才能让编译器满意?我想这与指定另一生有关,但尽管查看了这本书和许多在线资源,我仍无法找到正确的方法。
问题似乎出在该Sum
特征的生命周期参数上,这是一个不删除该特征的解决方案
fn compute_mean_of_vec<'g, T>(input_vec: &'g Vec<T>) -> T
where
for<'x> T: Copy
+ num::Zero
+ std::ops::Add<T, Output = T>
+ std::ops::Div<T, Output = T>
+ num::FromPrimitive
+ std::iter::Sum<&'x 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
for<'x> T: std::ops::SubAssign
+ Copy
+ num::traits::identities::Zero
+ std::ops::Div<Output = T>
+ num::traits::cast::FromPrimitive
+ std::iter::Sum<&'x 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);
}
}
Run Code Online (Sandbox Code Playgroud)
即,通过为 Trait 指定一个独立的生命周期参数Sum
,该参数'g
不会被假定为随整个函数一起携带。
归档时间: |
|
查看次数: |
622 次 |
最近记录: |