我可以写一个变异的Iterator,然后产生一个参考本身?

我碰到一个问题,简化为以下内容:

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); } } 

这会产生错误:

 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 

这个想法是,迭代器做了一堆反映在其字段中的工作,并且在每个步骤中,它都会产生对调用代码的引用。 在这种情况下,我可以把它build模为产生状态的副本而不是参考,但假设这是不可能的,或者只是不便宜的代价。

直观地说,这不应该是一个问题,因为借用检查器可以确保.next()不被再次调用,而仍然可以使用被引用的引用来检查迭代器的状态,但是Iterator特征似乎没有提供直接sorting 即使有些排列只是在迭代器本身中只保留一个引用,或者使迭代器成为一个引用或者一些东西来使得这个types的生命周期更早一些被烘焙,我也无法获得任何东西通过借用检查器。

我读了“ 产生可变引用的迭代器 ”blogpost,但是我不确定它是否适用于不涉及可变引用的问题。

这不可能。 如果允许的话,可以再次调用,从而修改也可以通过&可见的数据,甚至完全使参考无效。 这是因为self对象本身和返回的引用之间没有连接:没有明确的生命期连接它们。

对于编译器推理,允许返回一个引用到self接下来需要一个签名

 fn next(&'a mut self) -> Option<&'a [i8]> 

然而,这不同于不允许作为通用代码的特征的签名,它只需要一个T: Iterator<...>不能说明对某些T使用返回值有不同的要求; 都必须一致处理。

Iterator特征是为独立于迭代器对象的返回值而devise的,迭代器对象必须像迭代器适配器那样正确和安全。 这对于许多用途(例如for循环内的暂时使用)而言是比限制性更多的限制,但是现在是如此。 我认为我们现在没有适当的概括这个特征/ for循环的工具(具体地说,我认为我们需要更高级别生命周期的关联types),但是也许在将来。