Один простой способ сделать это - потребовать, чтобы итератор ввода возвращал ссылки. Это компилирует:
fn make_dyn<'b, I, S>(iter_in: I)
where
I: Iterator<Item = &'b S>,
S: Deref<Target = u8> + 'b,
{
let mut iter_out = iter_in.map(|s| -> &dyn Deref<Target = u8> {
s as _
});
take_dyn(&mut iter_out)
}
fn take_dyn<'a: 'b, 'b>(
_iter: &'a mut (dyn 'a + Iterator<Item = &'b (dyn 'b + Deref<Target = u8>)>),
) { }
Обратите внимание, что это хороший стиль, когда адаптеры итераторов возвращают итераторы, которыми можно управлять в дальнейшем:
fn make_dyn_<'b, I, S>(iter_in: I) -> impl Iterator<Item = &'b (dyn 'b + Deref<Target = u8>)>
where
I: Iterator<Item = &'b S>,
S: Deref<Target = u8> + 'b,
{
iter_in.map(|s| -> &dyn Deref<Target = u8> {
s as _
})
}
(Вы также можете определить это как generi c структура, реализующая черту Iterator
.)
Теперь: если вы не хотите требовать, чтобы итератор ввода возвращал ссылки, тогда нет возможности вернуть ваш новый итератор.
Что в примере кода вы создаете небольшой буфер внутри своего итератора и возвращаете на него ссылки.
Если этот буфер хранится в вашей структуре итератора, то, что вы пытаетесь создать, называется итератор потоковой передачи и не может быть реализован в настоящее время. Это очень длинное сообщение в блоге объясняет, почему; по сути, это потребует больших и сложных расширений системы типов Rust.
Вы можете сделать что-то подобное, если вы измените свой код, чтобы пользователи передавали замыкания в ваши функции. Затем вы контролируете, когда вызываются замыкания, поэтому вы можете сохранить возвращенные значения в буфере и передавать ссылки на буфер в замыкание. Но это не так эргономично c, как обычный Iterator
интерфейс.
Это вроде того, что вы сделали со своим примером кода ... Я не совсем уверен, почему это не работает . Если вы изменили take_dyn
на одиночный &'b (dyn 'b + Deref<Target = u8>)>
и неоднократно вызывали его, это должно работать.