当第二次调用另一个函数时,如何告诉编译器传递给函数的不可变引用不再存在?

How do I tell the compiler that immutable references passed into a function no longer exist when another function is called for the second time?

我遇到了生命周期问题:

fn solve_hanoi<'a>(
    a: &'a mut Vec<u8>,
    b: &'a mut Vec<u8>,
    c: &'a mut Vec<u8>,
    depth: u8,
    deshuffle: fn(&'a Vec<u8>, &'a Vec<u8>, &'a Vec<u8>) -> (&'a Vec<u8>, &'a Vec<u8>, &'a Vec<u8>),
) {
    if depth == 0 {
        return;
    } else {
        solve_hanoi(a, c, b, depth - 1, |a_, c_, b_| (a_, b_, c_));

        c.push(a.pop().unwrap()); // the actual move

        {
            let (a_, b_, c_) = deshuffle(a, b, c);
            print_hanoi(a_, b_, c_);
        }

        solve_hanoi(b, a, c, depth - 1, |b_, a_, c_| (a_, b_, c_));
    }
}

fn print_hanoi(_: &Vec<u8>, _: &Vec<u8>, _: &Vec<u8>) {}

deshuffle 的目的是确保打印的塔始终保持相同的顺序,即使参数中值的顺序发生变化。然而,编译器抱怨:

error[E0502]: cannot borrow `*b` as mutable because it is also borrowed as immutable
  --> src/lib.rs:20:9
   |
1  | fn solve_hanoi<'a>(
   |                -- lifetime `'a` defined here
...
16 |             let (a_, b_, c_) = deshuffle(a, b, c);
   |                                ------------------
   |                                |            |
   |                                |            immutable borrow occurs here
   |                                argument requires that `*b` is borrowed for `'a`
...
20 |         solve_hanoi(b, a, c, depth - 1, |b_, a_, c_| (a_, b_, c_));
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

error[E0502]: cannot borrow `*a` as mutable because it is also borrowed as immutable
  --> src/lib.rs:20:9
   |
1  | fn solve_hanoi<'a>(
   |                -- lifetime `'a` defined here
...
16 |             let (a_, b_, c_) = deshuffle(a, b, c);
   |                                ------------------
   |                                |         |
   |                                |         immutable borrow occurs here
   |                                argument requires that `*a` is borrowed for `'a`
...
20 |         solve_hanoi(b, a, c, depth - 1, |b_, a_, c_| (a_, b_, c_));
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

error[E0502]: cannot borrow `*c` as mutable because it is also borrowed as immutable
  --> src/lib.rs:20:9
   |
1  | fn solve_hanoi<'a>(
   |                -- lifetime `'a` defined here
...
16 |             let (a_, b_, c_) = deshuffle(a, b, c);
   |                                ------------------
   |                                |               |
   |                                |               immutable borrow occurs here
   |                                argument requires that `*c` is borrowed for `'a`
...
20 |         solve_hanoi(b, a, c, depth - 1, |b_, a_, c_| (a_, b_, c_));
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

我尝试了各种不同的生命周期注解组合,但总有一些问题。第二次调用solve_hanoi时,如何告诉编译器传递给deshuffle函数的不可变引用不再存在?

问题是您使用 'a 作为函数参数以及 abc 的生命周期。这意味着函数借用参数直到它们自己的生命周期结束。相反,您可能希望函数参数和 return 值有自己的生命周期:

fn solve_hanoi<'a>(
    a: &'a mut Vec<u8>,
    b: &'a mut Vec<u8>,
    c: &'a mut Vec<u8>,
    depth: u8,
    deshuffle: for<'b> fn(
        &'b Vec<u8>,
        &'b Vec<u8>,
        &'b Vec<u8>,
    ) -> (&'b Vec<u8>, &'b Vec<u8>, &'b Vec<u8>),
) {
    if depth == 0 {
        return;
    } else {
        solve_hanoi(a, c, b, depth - 1, |a_, c_, b_| (a_, b_, c_));

        c.push(a.pop().unwrap()); // the actual move

        {
            let (a_, b_, c_) = deshuffle(a, b, c);
            // print_hanoi(a_, b_, c_);
        }

        solve_hanoi(b, c, a, depth - 1, |b_, c_, a_| (a_, b_, c_));
    }
}

Playground link