Posso escrever um iterador que se transforma e depois gera uma referência em si mesmo?
Encontrei um problema que simplifica o seguinte:
struct MyIter {
vec: Vec<i8>,
}
fn fill_with_useful_data(v: &mut Vec<i8>) {
/* ... */
}
impl<'a> Iterator for MyIter {
type Item = &'a [i8];
fn next(&mut self) -> Option<&'a [i8]> {
fill_with_useful_data(&mut self.vec);
Some(&self.vec)
}
}
fn main() {
for slice in (MyIter { vec: Vec::new() }) {
println!("{}", slice);
}
}
Isso gera o erro:
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:9:6
|
9 | impl<'a> Iterator for MyIter {
| ^^ unconstrained lifetime parameter
A idéia é que o iterador faça um monte de trabalho que reflete em seus campos e, a cada etapa, produz uma referência em si mesmo ao código de chamada. Nesse caso, eu poderia modelá-lo como produzindo uma cópia do estado em vez da referência, mas vamos fingir que isso não é possível ou apenas inconvenientemente caro.
Intuitivamente, isso não deve ser um problema, porque o verificador de empréstimos pode garantir que.next()
não é chamado novamente enquanto a referência obtida ainda pode ser usada para inspecionar o estado do iterador, mas oIterator
a característica não parece fornecer esse tipo de coisa diretamente. Mesmo com algumas permutações como apenas manter uma referência ao vetor no próprio iterador ou fazer do iterador uma referência ou algo para obter as vidas úteis inseridas no tipo mais cedo, não consigo passar nada do verificador de empréstimo.
Eu li o "Iteradores que Produzem Referências Mutáveis"blogpost mas não tenho certeza se / como isso se aplica ao meu problema que não envolve referências mutáveis.