Web*_*ogz 2 mutable immutability rust borrowing
我正在制作一个组合优化项目来学习Rust,我遇到了一个问题,我无法解决自己...
我有两个功能:
pub fn get_pareto_front_offline<'a>(scheduling_jobs: &'a Vec<Vec<u32>>, costs_vector: &'a Vec<(u32, u32)>) -> Vec<(&'a Vec<u32>, &'a (u32, u32))> {
// ...
}
Run Code Online (Sandbox Code Playgroud)
和
pub fn pareto_approach_offline<'a>(list_of_jobs: &'a mut Vec<Vec<u32>>, neighborhood: &'a mut Vec<Vec<u32>>, costs: &'a Vec<(u32, u32)>) -> Vec<(&'a Vec<u32>, &'a (u32, u32))> {
let pareto_front = get_pareto_front_offline(neighborhood, costs);
loop {
if pareto_front == vec![] {
break;
}
neighborhood.clear();
for front in pareto_front.iter() {
neighborhood.push((front.0).clone());
}
}
pareto_front
}
Run Code Online (Sandbox Code Playgroud)
我有一个问题,因为编译器告诉我:
cannot borrow '*neighborhood' as mutable because it is also borrowed as immutableat line 15 col 9
cannot borrow '*neighborhood' as mutable because it is also borrowed as immutableat line 19 col 13
Run Code Online (Sandbox Code Playgroud)
你试图做一些根本不可能的事情.
当你打电话时get_pareto_front_offline,你会重新借用neighborhood该功能.必须维持此重新借入才能pareto_front保持有效.换句话说,只要pareto_front存在,编译器将不会允许您访问neighborhood以任何方式任何责任.
这是一件好事,因为你继续尝试清除我们的neighborhood,这几乎肯定会失效pareto_front,可能会导致使用后免费并破坏你的程序的状态.
目前尚不清楚你正在尝试做什么; 但你不能这样做.
顺便说一句,即使它被编译,该循环可能永远不会完成运行:你的终止条件(pareto_front == vec![])将永远不会被满足,因为你永远不会修改pareto_front; 它要么立即停止,要么永远运行.
摆脱借贷问题的最简单方法是复制东西,这样你就不需要长期借用; 如果get_pareto_front_offline返回一个Vec<(Vec<u32>, (u32, u32))>,你就不会有这个问题.那,或修改为代码,neighborhood一旦你打电话不接触get_pareto_front_offline.
在这种情况下,编译器通过不接受代码来帮助您避免释放后使用错误。问题可以简化为这段代码:
fn main() {
let mut v = vec![0,1,2,3];
let r = &v[2];
v.push(5);
println!("{}", *r); // oops
}
Run Code Online (Sandbox Code Playgroud)
Vec 有长度和容量。如果长度等于容量,则意味着缓冲区中没有剩余空间可用于新元素。在这种情况下,push涉及将所有元素移动到足以存储新数据的新缓冲区。但是此操作会使引用无效,r因为r仍然存储第三个向量元素的旧地址和现在无效地址。这正是 Rust 试图通过借用规则和借用检查器防止的那种错误。
但是如果你只是向向量添加新的东西,它不会改变已经在那里的元素的顺序。也许你可以用索引替换对 Vec 元素的一些引用,无论 Vec 元素存储在哪里,这些索引都保持不变。
抛开一些建议:不想&[T]过&Vec<T>的函数参数。它更灵活。此外,pareto_front == vec![]可以替换为pareto_front.is_empty().
| 归档时间: |
|
| 查看次数: |
1636 次 |
| 最近记录: |