2015-06-16 9 views
7

Sto tentando di implementare il tratto Iterator per una struttura che funge da prenditore di un array di valori i32, ma continuo a eseguire il compilatore lamentandosi di non essere in grado di dedurre una vita all'interno del prossimo metodo.Impossibile dedurre la durata appropriata per autoref quando si chiama un metodo da un'implementazione Iterator

Sono a conoscenza di Need help understanding Iterator lifetimes, ma poiché la mia struttura prende in prestito solo una parte dell'array in ogni caso, tengo la memoria degli elementi reali separata dal mio IntegerArrayBag.

#[derive(Debug)] 
struct IntegerArrayBag<'a> { 
    arr: &'a [i32], 
    idx: usize, 
} 

impl<'a> IntegerArrayBag<'a> { 
    fn len(&self) -> usize { 
     self.arr.len() 
    } 

    fn get(&self, idx: usize) -> Option<&i32> { 
     if self.arr.len() > idx { 
      Some(&self.arr[idx]) 
     } else { 
      None 
     } 
    } 
} 

impl<'a> Iterator for IntegerArrayBag<'a> { 
    type Item = &'a i32; 

    fn next(&mut self) -> Option<&'a i32> { 
     let idx = self.idx; 
     self.idx += 1; 
     self.get(idx) 
    } 
} 

Se provo a compilare this code, il compilatore si lamenta con:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements 
    --> src/main.rs:27:14 
    | 
27 |   self.get(idx) 
    |    ^^^ 
    | 
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 24:5... 
    --> src/main.rs:24:5 
    | 
24 |/ fn next(&mut self) -> Option<&'a i32> { 
25 | |   let idx = self.idx; 
26 | |   self.idx += 1; 
27 | |   self.get(idx) 
28 | |  } 
    | |_____^ 
note: ...so that reference does not outlive borrowed content 
    --> src/main.rs:27:9 
    | 
27 |   self.get(idx) 
    |   ^^^^ 
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 21:1... 
    --> src/main.rs:21:1 
    | 
21 |/impl<'a> Iterator for IntegerArrayBag<'a> { 
22 | |  type Item = &'a i32; 
23 | | 
24 | |  fn next(&mut self) -> Option<&'a i32> { 
... | 
28 | |  } 
29 | | } 
    | |_^ 
note: ...so that expression is assignable (expected std::option::Option<&'a i32>, found std::option::Option<&i32>) 
    --> src/main.rs:27:9 
    | 
27 |   self.get(idx) 
    |   ^^^^^^^^^^^^^ 

risposta

6

È necessario aggiornare il metodo di get per restituire un riferimento con la vita più lunga:

// Use 'a from impl<'a> IntegerArrayBag<'a> 
fn get(&self, idx: usize) -> Option<&'a i32> { 

e poi sarà la compilazione.

+0

Naturalmente. È separato dal sé, quindi devo anche dichiararlo in questo modo. Grazie. –

Problemi correlati