【问题标题】:error[E0502]: cannot borrow `cloned_game` as immutable because it is also borrowed as mutable错误[E0502]:不能将`cloned_game`借用为不可变的,因为它也被借用为可变的
【发布时间】:2021-04-11 09:18:15
【问题描述】:

我是 Rust 的新手。我正在尝试使用递归解决问题。在递归函数中,我克隆了游戏的状态,然后从向量中获取每对元素并使用try_add_to() 对其进行变异,然后检查游戏是否已解决。

fn try_find_solution(game: &GameState) -> Option<GameState> {
    let mut cloned_game = game.clone();

    for split_index in 1..cloned_game.cups.len() - 1 {
        // Need two mutable references from the vector. Use split_at_mut() to allow this.
        let (a, b) = cloned_game.cups.split_at_mut(split_index);
        let first_cup = a.last_mut().unwrap();

        for second_cup in b.iter_mut() {
            if first_cup.try_add_to(second_cup) || second_cup.try_add_to(first_cup) {
                if cloned_game.is_solved() {
                    return Some(cloned_game);
                }
                else {
                    // let solution = try_find_solution(&cloned_game);
                    // @TODO.
                }
            }
        }
    }

    None
}

我遇到了以下错误。

error[E0502]: cannot borrow `cloned_game` as immutable because it is also borrowed as mutable
  --> src/main.rs:31:20
   |
26 |         let (a, b) = cloned_game.cups.split_at_mut(split_index);
   |                      ---------------- mutable borrow occurs here
...
30 |             if first_cup.try_add_to(second_cup) || second_cup.try_add_to(first_cup) {
   |                --------- mutable borrow later used here
31 |                 if cloned_game.is_solved() {
   |                    ^^^^^^^^^^^ immutable borrow occurs here

我想我理解为什么会发生此错误,但如果不完全重新设计解决方案,我不知道如何解决它。有什么我可以做的吗?

【问题讨论】:

    标签: rust borrow-checker


    【解决方案1】:

    如果这是您尝试暴力破解某些东西,我可能不会使用递归。除了最简单的解决方案之外,您可能会达到递归限制。此外,您将不得不进行过多的克隆,因为每个堆栈都会对游戏状态进行自己的克隆。

    至于你原来的问题,最好的办法是避免同时持有这些引用。

    例如,这不会编译:

    fn hello_world(s: &mut [u8]){
        let (a,b) = s.split_at_mut(1);
        let c = s.len();
        drop((a,b,c));
    }
    

    ...但确实如此:

    fn hello_world(s: &mut [u8]){
        let (a,b) = s.split_at_mut(1);
        drop((a,b));
        
        let c = s.len();
        drop(c);
    }
    

    ...因为我们没有强行将ab 坚持到底。如果您可以将.is_solved() 调用提取到循环外,那应该可以。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多