为什么可变参考没有移到这里? [英] Why is the mutable reference not moved here?
问题描述
我的印象是可变引用(即&mut T
)总是移动的.这是完全合理的,因为它们允许独占的可变访问.
在下面的代码中,我将一个可变引用分配给另一个可变引用,然后移动原始引用.结果,我不能再使用原始文件了:
I was under the impression that mutable references (i.e. &mut T
) are always moved. That makes perfect sense, since they allow exclusive mutable access.
In the following piece of code I assign a mutable reference to another mutable reference and the original is moved. As a result I cannot use the original any more:
let mut value = 900;
let r_original = &mut value;
let r_new = r_original;
*r_original; // error: use of moved value *r_original
如果我有这样的功能:
fn make_move(_: &mut i32) {
}
并修改我的原始示例,使其看起来像这样:
and modify my original example to look like this:
let mut value = 900;
let r_original = &mut value;
make_move(r_original);
*r_original; // no complain
当我用它调用函数make_move
时,我希望可变引用r_original
被移动.但是,这不会发生.通话结束后,我仍然可以使用参考.
I would expect that the mutable reference r_original
is moved when I call the function make_move
with it. However that does not happen. I am still able to use the reference after the call.
如果我使用通用函数make_move_gen
:
fn make_move_gen<T>(_: T) {
}
并这样称呼它:
let mut value = 900;
let r_original = &mut value;
make_move_gen(r_original);
*r_original; // error: use of moved value *r_original
该引用再次移动,因此该程序的行为符合我的预期.
为什么在调用函数make_move
时引用没有移动?
The reference is moved again and therefore the program behaves as I would expect.
Why is the reference not moved when calling the function make_move
?
推荐答案
实际上可能有充分的理由.
There might actually be a good reason for this.
&mut T
实际上不是 一种类型:所有借用都经过某些(可能无法表达)生命周期的参数化.
&mut T
isn't actually a type: all borrows are parametrized by some (potentially inexpressible) lifetime.
当一个人写
fn move_try(val: &mut ()) {
{ let new = val; }
*val
}
fn main() {
move_try(&mut ());
}
类型推断引擎推断typeof new == typeof val
,因此它们共享原始生存期.这意味着从new
借用直到val
借用才结束.
the type inference engine infers typeof new == typeof val
, so they share the original lifetime. This means the borrow from new
does not end until the borrow from val
does.
这意味着它等同于
fn move_try<'a>(val: &'a mut ()) {
{ let new: &'a mut _ = val; }
*val
}
fn main() {
move_try(&mut ());
}
但是,当你写
fn move_try(val: &mut ()) {
{ let new: &mut _ = val; }
*val
}
fn main() {
move_try(&mut ());
}
发生强制转换-与使指针强制可变性消失的方法相同.这意味着寿命是某些(看似无法指定)'b < 'a
.这涉及强制转换,因此涉及重新借入,因此重新借入能够超出范围.
a cast happens - the same kind of thing that lets you cast away pointer mutability. This means that the lifetime is some (seemingly unspecifiable) 'b < 'a
. This involves a cast, and thus a reborrow, and so the reborrow is able to fall out of scope.
总是重借的规则可能会更好,但是显式声明并不太成问题.
An always-reborrow rule would probably be nicer, but explicit declaration isn't too problematic.
这篇关于为什么可变参考没有移到这里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!