2014-08-27 64 views
4

下面是一些我的行爲上絆了小例子:爲什麼借閱檢查員讓我做兩個可變借款?

pub struct PrimeEngine { 
    primes: Vec<uint>, 
} 

pub struct PrimeIterator<'a> { 
    engine: &'a mut PrimeEngine, 
    index: uint 
} 

impl PrimeEngine { 
    pub fn new() -> PrimeEngine { 
     PrimeEngine { primes: vec![] } 
    } 

    // Needs a &mut so it can call more_primes if needed 
    pub fn is_prime(&mut self, x: uint) -> bool { 
     true 
    } 

    pub fn iter<'a>(&'a mut self) -> PrimeIterator<'a> { // ' 
     PrimeIterator { engine: self, index: 0 } 
    } 

    fn more_primes(&mut self) { 
     // Adds more primes to self.primes 
    } 
} 

impl<'a> Iterator<uint> for PrimeIterator<'a> { 
    fn next(&mut self) -> Option<uint> { 
     if self.engine.primes.len() <= self.index { 
      self.engine.more_primes(); 
     } 
     let i = self.index; 
     self.index += 1; 
     Some(self.engine.primes[i]) 
    } 
} 

創建時,下面的代碼無法編譯,因爲它試圖使engine 2個可變借力,創造一次關閉時,再次迭代器:

#[test] 
fn test1() { 
    let mut engine = PrimeEngine::new(); 
    engine.iter().take(5).inspect(|x| { 
     assert!(engine.is_prime(*x)) 
    }); 
} 

此代碼然而,這編譯:

#[test] 
fn test2() { 
    let mut engine = PrimeEngine::new(); 
    for x in engine.iter().take(5) { 
     assert!(engine.is_prime(x)) 
    } 
} 

而且我不知道爲什麼。它需要做一個可變借款engine來創建Iterator,這將防止它產生需要調用is_prime的可變借入。這是否因爲某種原因而被允許?或者它是一個錯誤?

回答

4

我看起來像一個錯誤,我設法重現此問題與簡單的代碼:

fn main() { 
    let mut vector = vec!(1u, 2u); 
    for &x in vector.iter() { 
     let cap = vector.capacity(); 
     println!("Capacity was: {}", cap); 
     vector.grow(cap, &0u); // be sure to cause reallocation 
     *vector.get_mut(1u) = 5u; 
     println!("Value: {}", x); 
    } 
} 

它輸出:

Capacity was: 4 
Value: 1 
Capacity was: 8 
Value: 2 

我修改矢量內容和重新分配,造成底層切片來引用未分配的內存(vector.iter()實際上是vector.as_slice().iter())。

它看起來像一個最近的變化,由於雙重借用它不會在鏽0.11上編譯。

我這裏開一個問題:https://github.com/rust-lang/rust/issues/16820

編輯(2014年9月10日):該錯誤是現予以更正:https://github.com/rust-lang/rust/pull/17101

相關問題