2015-11-29 29 views
1

我正在做一个组合优化项目学习锈蚀和我有一个问题,我解决不了自己...不能借`* x`为可变,因为它是还借为不可改变

我已经有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 

回答

5

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

当您拨打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))>,则不会有此问题。一旦你拨打get_pareto_front_offline,或者修改代码以不触及neighborhood

+0

谢谢!你的解决方案正是我的想法......我试图为这个问题制定一个优化的解决方案,但是用我在Rust的“水平”,这真的很难: -/ – WebTogz

+0

在这种情况下,你经常需要一个专门的采集。我认为,'VecDeque'可以解决问题,(但我可能是错的) https://doc.rust-lang.org/std/collections/struct.VecDeque.html 或者您可以使用渠道 https://doc.rust-lang.org/std/sync/mpsc/ – nielsle

2

在这种情况下,编译器通过不接受代码来帮助您避免使用后错误。这个问题可以简化为这段代码:

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()

相关问题