2015-02-11 31 views
4

以下兩行的盒時Collat​​erally移動誤差解構對

error[E0382]: use of moved value: `x` 
--> src/main.rs:3:13 
    | 
3 |  let (a, b) = *x; 
    |   -^value used here after move 
    |   | 
    |   value moved here 
    | 
    = note: move occurs because `x.0` has type `std::string::String`, which does not implement the `Copy` trait 

有趣的是,如果我這樣做與枚舉類型與多個零件 ,我得到一個稍微不同的錯誤:

enum Tree { 
    Nil, 
    Pair(Box<Tree>, Box<Tree>), 
} 

fn main() { 
    let x = Box::new(Tree::Nil); 

    match *x { 
     Tree::Pair(a, b) => Tree::Pair(a, b), 
     _ => Tree::Nil, 
    }; 
} 

我得到th E錯誤:

error[E0382]: use of collaterally moved value: `(x:Tree::Pair).1` 
    --> src/main.rs:10:23 
    | 
10 |   Tree::Pair(a, b) => Tree::Pair(a, b), 
    |     -^value used here after move 
    |     | 
    |     value moved here 
    | 
    = note: move occurs because `(x:Tree::Pair).0` has type `std::boxed::Box<Tree>`, which does not implement the `Copy` trait 

爲什麼會發生這種情況,我怎麼能輕易破壞結構與let/match,讓內部零件的所有權?我知道我可以首先解引用並命名結構,但是如果我將模式匹配深入到結構中,則會變得非常冗長。

回答

5

你偶然發現了limitation on destructuring and boxes。幸運的是,解決這些問題很容易。所有你需要做的是推出一個包含整個結構一個新的中介變量,解構來自:

let x = Box::new(("slefj".to_string(), "a".to_string())); 
let pair = *x; 
let (a, b) = pair; 

第二個例子:

let pair = *x; 
match pair { 
    Tree::Pair(a, b) => Tree::Pair(a, b), 
    _ => Tree::Nil, 
}; 
+0

我也感到驚訝你不能上使用的盒子作爲'讓Box((a,b))= x;'的左邊,我把它作爲[#22207](https://github.com/rust-lang/rust/issues/22207)提交。 – Shepmaster 2015-02-12 05:01:26

+1

使用'box'語法是可能的,但是這是目前功能門控(並且可能會改變)。不確定使用'Box'(結構體)解構是否應該立即工作 – 2015-02-12 05:04:40

+0

是否有另一種解決方法,不需要在結構的每一層都有中間綁定?這種解決方法使深入匹配結構非常冗長。 – 2015-02-12 16:23:25