2016-03-28 12 views
0

私は、列挙型、2つの構造体とBTreeMapとファイルシステムのような構造をモデル化し、この(簡体字)のように:再帰的に訪問し、列挙型

pub enum Item { 
    Dir(Dir), 
    File(File), 
} 

struct Dir { 
    ... 
    children: BTreeMap<String, Item>, 
} 

struct File { 
    ... 
} 

今、私はディレクトリをループする必要があり、いくつかの操作を行いすべてのファイルに対する操作。私はこの試みた:

fn process(index: &Dir) { 
    for (_, child) in index.children { 
     match child { 
      Item::File(mut f) => { 
       let xyz = ...; 
       f.do_something(xyz); 
      }, 
      Item::Dir(d) => { 
       process(&d); 
      } 
     } 
    } 
} 

を私は得る:私も

for (_, child) in index.children.iter() { 

を試してみました

error: cannot move out of borrowed content [E0507] 
     for (_, child) in index.children { 
         ^~~~~ 

が、その後、私は、私はいくつかの組み合わせを試してみました

error: mismatched types: 
expected `&Item`, 
    found `Item` 
(expected &-ptr, 
    found enum `Item`) [E0308] 
src/... Item::File(mut a) => { 
     ^~~~~~~~~~~~~~~~~ 

取得:

for (_, child) in &(index.children) 
for (_, child) in index.children.iter().as_ref() 

match(child) { Item::File(&mut f) => 
match(child) { Item::File(ref mut f) => 

などですが、借用チェッカーを幸せにする方法が見つかりませんでした。

ご迷惑をおかけして申し訳ありません。

答えて

2

コードにはいくつかの問題があります。反復にchildrenを移動するfor /* ... */ in index.children試行を言っ

fn process(index: &mut Dir) { 
    //    ^^^-- #2 
    for (_, child) in &mut index.children { 
     //    ^^^-- #1 
     match *child { 
      //^-- #3 
      Item::File(ref mut f) => { 
       //  ^^^-- #4 
       f.do_something(); 
      }, 
      Item::Dir(ref mut d) => { 
       // ^^^-- #4 
       process(d); 
      } 
     } 
    } 
} 
  1. :ここでは、番号変更を伴う作業バージョンです。その理由を説明しているSOには、すでにsomeanswersがあります。我々は消費せずに反復したいが、値を変更することができる。
  2. (1)機能もDir
  3. child可変の参照を持っている必要がありますタイプ&mut Itemの可変リファレンスであるのので(それは何イテレータ利回りだから)。照合ブロックのパターン(例:Item::File(/* ... */))はItemです。これは型の不一致(2番目のコンパイラエラー)です。 childを逆参照することで解決できます。*です。
  4. matchブロックはItemと一致しますが、実際にアイテムを所有しているわけではありません。移動できません。移動を防ぐため、refというキーワードを追加します。今度はfdが参考になり、動きは避けました。
+0

ありがとうございます!あなたの説明は1 .iter()(参照を返すため)を使用しようとした理由です。 マニュアル全体、&mut、ref、*、そしてそれらを使うことができる場所が非常に混乱していました。関数の引数や呼び出しパラメータで使われたときの動作ははっきりしていますが、for ...やa *の後に&mutを使ったことはありませんでした。 – Shu

関連する問題