У меня есть код, который выглядит (немного) примерно так:
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);
}
}
По сути, пользователь может предоставить итератор входных данных, а затем получить итератор выходных данных (в моем реальном коде Соединение между входами и выходами намного сложнее, включая множество внутренних состояний. Несколько входов могут go к одному выходу или наоборот).
Это работает, но я бы хотел изменить его, используя impl Iterator
чтобы скрыть тип OutputIterator
и упростить замену возвращаемого типа при тестировании с фальшивкой. Моя лучшая попытка изменить это на InputHandler:
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
, здесь меньше из этих двух? Любая ясность относительно того, почему эта ошибка происходит или как ее исправить, была бы великолепна!
В случае, если это поможет, вот ржавчина с кодом в ней.