Если вы посмотрите на определение StreamExt::map
, которое автоматически реализуется типами, которые реализуют Stream
, вы увидите это:
fn map<T, F>(self, f: F) -> Map<Self, F>
where
F: FnMut(Self::Item) -> T
Другими словами, map
становится владельцем self
. Но Box<dyn Stream>
не реализует Stream
, поэтому вместо этого он попытается использовать значение dyn Stream
, содержащееся в нем. Но это объект trait, который имеет тип без размера и никогда не может быть параметром self
без ссылки, поэтому ваша ошибка компилятора.
Решением здесь было бы изменить тип возвращаемого значения на <a href="https://doc.rust-lang.org/stable/std/pin/struct.Pin.html" rel="noreferrer">Pin</a><Box<dyn Stream<Item = ()>>>
, который делает реализации Stream
:
use std::pin::Pin;
fn stream_it() -> Pin<Box<dyn Stream<Item=()>>> {
// ^-- add Pin<...> here
Box::pin(futures::stream::iter(vec![(), (), ()]))
// ^-- use Box::pin instead of Box::new
}
В качестве альтернативы, вы также можете изменить тип возврата на Box<dyn Stream<Item = ()> + <a href="https://doc.rust-lang.org/stable/std/marker/trait.Unpin.html" rel="noreferrer">Unpin</a>>
, который также реализует Stream
, но добавляет некоторые дополнительные требования к потоку, который возвращается (а именно, что он реализует Unpin
и, следовательно, безопасно перемещаться в памяти), поэтому он, как правило, менее предпочтителен.