此代码在let c = a;
处出现错误,编译错误"使用移动的值:a
":
fn main() {
let a: &mut i32 = &mut 0;
let b = a;
let c = a;
}
a被移入b并且不再可用于c的赋值。到目前为止,非常好。
但是,如果我只是注释b
的类型并将其他所有内容保留下来:
fn main() {
let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
let c = a;
}
代码在let c = a;
但这一次有一个非常不同的错误消息:"无法移出a
,因为它是借来的......借用*a
在这里:let b: &mut i32 = a;
&# 34;
所以,如果我只是注释b
的类型:a
没有移动到b
,而是一个" re" -borrow of *a
?
我错过了什么?
干杯。
答案 0 :(得分:7)
所以,如果我只注释
b
的类型:a
没有移动到b
,而是*a
的“重新”借用?我错过了什么?
绝对没有,因为在这种情况下,这两个操作在语义上非常相似(如果a
和b
属于同一范围,则等效)。
a
移至b
,使a
成为移动的值,并且不再可用。*a
中重新展示b
,只要a
在范围内,b
就无法使用。第二种情况不如第一种情况明确,你可以通过将定义b
的行放入子范围来证明这一点。
此示例无法编译,因为移动了a
:
fn main() {
let a: &mut i32 = &mut 0;
{ let b = a; }
let c = a;
}
但是这一个会,因为一旦b
超出范围a
,就会解锁:
fn main() {
let a: &mut i32 = &mut 0;
{ let b = &mut *a; }
let c = a;
}
现在,对于“为什么注释b
的类型会改变行为?”这个问题,我的猜测是:
&mut _
转换为&_
,或将简单引用转换为对特征对象的引用)。因此,编译器选择重新借用值,而不是移动。例如,此代码非常有效:
fn main() {
let a: &mut i32 = &mut 0;
let b: &i32 = a;
}
此处将a
移动到b
中没有任何意义,因为它们属于不同的类型。这段代码仍在编译:{{1}}只是重新借用b
,只要*a
在范围内,a
就无法透明地提供该值。