我的代码看起来(有点)像这样。
struct OutputIterator<'r, 'i: 'r> {
input_handler: &'r mut InputHandler<'i>
}
impl<'r, 'i> Iterator for OutputIterator<'r, 'i> {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
self.input_handler.inputs.next().map(|x| x * 2)
}
}
struct InputHandler<'a> {
inputs: Box<dyn Iterator<Item = i32> + 'a>
}
impl<'a> InputHandler<'a> {
fn outputs<'b>(&'b mut self) -> OutputIterator<'b, 'a> {
OutputIterator { input_handler: self }
}
}
fn main() {
let mut input_handler = InputHandler {
inputs: Box::new(vec![1,2,3,4,5].into_iter())
};
for output in input_handler.outputs() {
println!("{}", output);
}
}
基本上,用户可以提供一个输入的迭代器,然后得到一个输出的迭代器(在我真正的代码中,输入和输出之间的连接要复杂得多,涉及一堆内部状态。多个输入可能走向一个输出,反之亦然)。)
这样做是可行的,但我想把它改为使用 impl Iterator
既要掩盖 OutputIterator
类型,并允许在测试中更容易地用一个假的返回类型进行替换。我最好的尝试是这样修改InputHandler impl。
impl<'a> InputHandler<'a> {
fn outputs<'b>(&'b mut self) -> impl Iterator<Item = i32> + 'b {
OutputIterator { input_handler: self }
}
}
不幸的是,这让我。error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
有什么办法能让它工作?对于接口来说,重要的是 InputHandler
取一个具有一定寿命的迭代器,这显然要传递给 OutputIterator
某种程度上,但我真的很想把这些细节从调用者那里抽象出来。原则上,调用者应该只需要担心是否确保输入的 Iterator
和 InputHandler
超生 OutputIterator
所以,我认为逻辑上的寿命约束在 OutputIterator
这里是这两个中较小的一个?如果能弄清楚为什么会出现这个错误,或者如何解决这个问题,那就太好了!
如果有帮助,这里有一个 锈迹斑斑 与其中的代码。
使用以下的变通方法 https:/github.comrust-langrustissues34511#issuecomment-373423999。,通过 https:/stackoverflow.coma505485381757964。:
trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
impl<'a> InputHandler<'a> {
fn outputs<'b>(&'b mut self) -> impl Iterator<Item = i32> + Captures<'a> + 'b {
OutputIterator { input_handler: self }
}
}