2017-07-04 23 views
3

我在enum上有一個迭代器,它在其中一個變體中具有可變引用。現在我想將此參考移出self並返回。爲避免同時對同一個對象有兩個可變引用,我想將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, 
     } 
    } 
} 
相關問題