如果我执行以下操作,则会收到错误消息:
struct A;
struct B;
fn consume_a(_a: A) {}
fn consume_b(_b: B) {}
struct C(A, B);
impl C {
fn foo(self: Self) {
consume_a(self.0);
consume_b(self.1);
}
}
fn main() {
let c = Box::new(C(A, B));
// Consume internals
let _a = c.0;
let _b = c.1;
}
error[E0382]: use of moved value: `c`
--> src/main.rs:21:9
|
20 | let _a = c.0;
| -- value moved here
21 | let _b = c.1;
| ^^ value used here after move
|
= note: move occurs because `c.0` has type `A`, which does not implement the `Copy` trait
我可以实现同样的事情(消耗内部)这样做:
fn main() {
let c = Box::new(C(A, B));
c.foo();
}
它的工作方式( c.foo()
)意味着我已经移出了盒装内容;怎么会发生这种情况? Box
文档中的API都没有显示我可以获取包含的值作为类型(即所有方法返回 &T
或 &mut T
但不返回 T
)
2 回答
您的原始代码在启用非词法生存期时有效:
这表明原始的失败只是借入检查者的弱点 .
正如您在方法中看到的那样,移出
Box
中的struct 's field directly works fine, but moving out of a field of a struct that'将首先从Box
移出一个临时变量,然后移出该临时变量的字段 . 因此,当您尝试移出第二个字段时,Box
已经被破坏并且's just a temporary left that you can' t使用了 .你可以通过自己创建临时工作来完成这项工作: