混淆了框内结构字段的移动语义

ust*_*ion 5 rust

如果我执行以下操作,则会收到错误消息:

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;
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

我可以实现同样的事情(消耗内部)这样做:

fn main() {
    let c = Box::new(C(A, B));
    c.foo();
}
Run Code Online (Sandbox Code Playgroud)

它在上面的工作方式(c.foo())意味着我已经移出了盒装内容; 怎么会发生这种情况?Box文档中的API都没有显示我可以获取包含的值作为类型(即所有方法返回&T&mut T不返回T)

oli*_*obk 6

正如你在方法中看到的那样,移出struct的字段直接工作正常,但是移出一个struct中的一个字段的字段Box首先移出Box一个临时变量,然后移出该临时字段的字段.因此,当你试图移出第二个字段时,Box它已经被破坏了,只有一个你不能使用的临时左边.

你可以通过自己创建临时工作来完成这项工作:

let c2 = *c;
let _a = c2.0;
let _b = c2.1;
Run Code Online (Sandbox Code Playgroud)

  • `Box`很特别.如果您取消引用"Box",您将获得内在价值.还没有办法为你自己的类型实现这个,但它有一个RFC:https://github.com/rust-lang/rfcs/pull/1646 (2认同)