4

我正在做一个组合优化项目来学习 Rust,但我遇到了一个我自己无法解决的问题......

我有 2 个功能:

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))> {
    // ...
}

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
}

我遇到了一个问题,因为编译器告诉我:

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
4

2 回答 2

6

你正在尝试做一些根本不可能的事情。

当您调用 时get_pareto_front_offline,您会将重新借用的内容传递给neighborhood该函数。必须维持此重新借用pareto_front以保持有效。换句话说,只要pareto_front存在,编译器就不允许你以neighborhood任何方式访问。

这是一件好事,因为然后您继续尝试清除我们的neighborhood,这几乎肯定会使 无效pareto_front,可能导致释放后使用并破坏您的程序状态。

目前尚不清楚您要做什么。但你不能这样做。

顺便说一句,即使它已编译,该循环也可能永远不会完成运行:您的终止条件 ( pareto_front == vec![]) 将永远不会满足,因为您从未修改pareto_front; 它要么立即停止,要么永远运行。

摆脱借款不足问题的最简单方法是复制东西,这样您就不需要长期借款;如果get_pareto_front_offline返回 aVec<(Vec<u32>, (u32, u32))>而不是,您将不会遇到此问题。那个,或者修改代码以neighborhood在你调用get_pareto_front_offline.

于 2015-11-29T16:47:17.213 回答
5

在这种情况下,编译器通过不接受代码来帮助您避免 use-after-free 错误。问题可以归结为这段代码:

fn main() {
    let mut v = vec![0,1,2,3];
    let r = &v[2];
    v.push(5);
    println!("{}", *r); // oops
}

Vec 具有长度和容量。如果长度等于容量,则意味着缓冲区中没有空间可供新元素使用。在这种情况下,push需要将所有元素移动到一个足够大以存储新数据的新缓冲区。但是这个动作会使引用无效,r因为r仍然存储旧的和现在无效的第三个向量元素的地址。这正是 Rust 试图通过借用规则和借用检查器来防止的那种错误。

但是如果你只是在向量中添加新的东西,它不会改变已经存在的元素的顺序。也许你可以用索引替换一些对 Vec 元素的引用,无论 Vec 元素存储在哪里,这些索引都保持不变。

一些建议:更喜欢&[T]函数&Vec<T>参数。它更灵活。此外,pareto_front == vec![]可以替换为pareto_front.is_empty().

于 2015-12-02T18:06:39.463 回答