2017-07-04 2 views
3

enumのイテレータは、そのバリアントの1つに可変参照があります。今私はこの参照をselfに移動して返したいと思います。同時に同じオブジェクトへの2つの可変参照を避けるために、selfの列挙型を参照を持たないものに変更したいと思います。次のコード例である:可変オブジェクトから可変参照を移動する

enum Test<'a> { 
    A(&'a mut usize), 
    B, 
} 

impl<'a> Iterator for Test<'a> { 
    type Item = &'a mut usize; 

    fn next(&mut self) -> Option<Self::Item> { 
     match *self { 
      Test::A(r) => Some(r), // TODO: return mutable reference and change self to B 
      Test::B => None, 
     } 
    } 
} 

fn main() { 
    let mut v = 1; 
    let mut it = Test::A(&mut v); 
    it.next(); 
} 

質問はChange selector in match when selector is a mutable referenceに関連しているが、そのソリューションは、ここでは動作しません。

答えて

3

私はswapを使用します。

fn next(&mut self) -> Option<Self::Item> { 
    if let Test::A(_) = *self { 
     let mut to_swap = Test::B; 

     std::mem::swap(self, &mut to_swap); 
     match to_swap { 
      Test::A(r) => Some(r), 
      _   => unreachable!(), // never reached 
     } 
    } else { 
     None 
    } 
} 

あなたは次のようにヘルパー関数を使用することができます。

impl<'a> Iterator for Test<'a> { 
    type Item = &'a mut usize; 

    fn next(&mut self) -> Option<Self::Item> { 
     if let Test::A(_) = *self { 
      let mut to_swap = Test::B; 

      std::mem::swap(self, &mut to_swap); 
      to_swap.consume_as_a() 
     } else { 
      None 
     } 
    } 
} 

impl<'a> Test<'a> { 
    fn consume_as_a(self) -> Option<&'a mut usize> { 
     match self { 
      Test::A(r) => Some(r), 
      _   => None, 
     } 
    } 
} 
関連する問題