"按引用传递"和"通过Box传递"将值传递给函数之间的区别是什么:
fn main() {
let mut stack_a = 3;
let mut heap_a = Box::new(3);
foo(&mut stack_a);
println!("{}", stack_a);
let r = foo2(&mut stack_a);
// compile error if the next line is uncommented
// println!("{}", stack_a);
bar(heap_a);
// compile error if the next line is uncommented
// println!("{}", heap_a);
}
fn foo(x: &mut i32) {
*x = 5;
}
fn foo2(x: &mut i32) -> &mut i32 {
*x = 5;
x
}
fn bar(mut x: Box<i32>) {
*x = 5;
}
为什么heap_a
被移入函数,但stack_a
没有被移入函数(在调用foo()
后的println!
语句中仍然可以使用stack_a
)?取消注释
println!("{}", stack_a);
会出现错误:error[E0502]: cannot borrow `stack_a` as immutable because it is also borrowed as mutable
--> src/main.rs:10:20
|
8 | let r = foo2(&mut stack_a);
| ------- mutable borrow occurs here
9 | // compile error if the next line is uncommented
10 | println!("{}", stack_a);
| ^^^^^^^ immutable borrow occurs here
...
15 | }
| - mutable borrow ends here
我认为这个错误可以通过引用生命周期来解释。对于foo
的情况,main
函数中的stack_a
被移动到函数foo
中,但编译器发现函数foo
的参数x:&mut i32
的生命周期在foo
的结尾处结束。因此,在foo
返回后,它允许我们在main
函数中使用变量stack_a
。对于foo2
的情况,stack_a
也被移动到函数中,但我们还将其返回。
为什么heap_a
的生命周期不会在bar
的结尾处结束?