我有一段代码如下:
fn stream_it(&self) -> Box<dyn Stream<Item=()>> {
Box::new(self.some_field)
}
fn consume_it(&self) {
let a = self.stream_it().map(|i| i);
}
我收到编译错误:
error: the `map` method cannot be invoked on a trait object
--> ...
|
69 | let a = self.stream_it().map(|i| i);
| ^^^
|
::: ...
|
257 | Self: Sized,
| ----- this has a `Sized` requirement
|
= note: other candidates were found in the following traits, perhaps add a `use` for one_of_them:
candidate #1: `use futures_util::future::future::FutureExt;`
candidate #2: `use futures_signals::signal::signal::SignalExt;`
candidate #3: `use futures_util::stream::stream::StreamExt;`
candidate #4: `use futures_signals::signal_vec::SignalVecExt;`
candidate #5: `use async_std::stream::stream::StreamExt;`
据我了解,Sized
需求是必要的,但我不知道如何实现。甚至可以映射单元流吗?
如果你看一下定义StreamExt::map https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.map,它由实现的类型自动实现Stream https://docs.rs/futures/0.3.4/futures/stream/trait.Stream.html,你会看到这个:
fn map<T, F>(self, f: F) -> Map<Self, F>
where
F: FnMut(Self::Item) -> T
换句话说,map
取得所有权self
. But Box<dyn Stream>
不执行Stream
,因此它将尝试使用dyn Stream
内含的价值。但这是一个特征对象,它是一个未调整大小的类型,并且永远不可能是一个self
参数没有引用,因此编译器错误。
这里的解决方案是将返回类型更改为Pin https://doc.rust-lang.org/stable/std/pin/struct.Pin.html<Box<dyn Stream<Item = ()>>>
, which does实施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 = ()> + Unpin https://doc.rust-lang.org/stable/std/marker/trait.Unpin.html>
,这也实现了Stream
,但对返回的流提出了一些额外的要求(即它实现Unpin
因此在内存中移动是安全的),因此通常不太可取。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)