2016-07-07 14 views
4

私は次のことを行うと、私はエラーを取得する:ボックス

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'sドキュメントのAPIののなしあなたは、構造体のフィールドの外に移動し、この方法で見ることができるように、私は(つまり、すべてのメソッドが&T&mut TではなくTを返す)型として

答えて

6

を含まれている値を取得することができますショーは直接正常に動作します。しかし、Boxにある構造体のフィールドから移動すると、最初にBoxから一時変数に移動し、その一時的なフィールドの外に移動します。したがって、2番目のフィールドから移動しようとすると、Boxはすでに破壊されており、使用できない一時的な残しがあります。

あなた自身の一時を作成することで、この作業を行うことができます。

let c2 = *c; 
let _a = c2.0; 
let _b = c2.1; 
+0

しかし '* C 'はありませんどちらか'&C'や '&MUT C' yeild必要がありますか?それでは 'let _a = c2.0;はどのように許されますか?それも私の質問の一つです。 – ustulation

+2

'Box'は特別です。 'Box'を逆参照すると、内側の値が得られます。あなた自身のタイプのためにこれを実装する方法はまだありませんが、RFCがあります:https://github.com/rust-lang/rfcs/pull/1646 –

+0

ああ。申し訳ありませんが、さらに混乱してしまいましたが、 'let c2 = * c;'が 'Box'から抜け出してあなたが言ったように一時的に作成すると、それが' trait'の 'Box'ならどうなりますか?コンパイラは一時的にスタックに割り当てるサイズを知っていますか? – ustulation