tokio::sync::mpsc::Sender
タスクに入力を送信するタスク、tokio::sync::mpsc::Receiver
タスクからの出力を受信するタスク、および最後に参加できるハンドルを使用して、Tokio タスクを管理する構造体を作成しようとしています。
use tokio::sync::mpsc;
use tokio::task::JoinHandle;
// A type that implements BlockFunctionality consumes instances of T and
// produces either Ok(Some(U)) if an output is ready, Ok(None) if an output
// is not ready, or an Err(_) if the operation fails
pub trait BlockFunctionality<T, U> {
fn apply(&mut self, input: T) -> Result<Option<U>, &'static str>;
}
pub struct Block<T, U> {
pub tx_input: mpsc::Sender<T>,
pub rx_output: mpsc::Receiver<U>,
pub handle: JoinHandle<Result<(), &'static str>>,
}
impl<T: Send, U: Send> Block<T, U> {
pub fn from<B: BlockFunctionality<T, U> + Send>(b: B) -> Self {
let (tx_input, mut rx_input) = mpsc::channel(10);
let (mut tx_output, rx_output) = mpsc::channel(10);
let handle: JoinHandle<Result<(), &'static str>> = tokio::spawn(async move {
let mut owned_b = b;
while let Some(t) = rx_input.recv().await {
match owned_b.apply(t)? {
Some(u) => tx_output
.send(u)
.await
.map_err(|_| "Unable to send output")?,
None => (),
}
}
Ok(())
});
Block {
tx_input,
rx_output,
handle,
}
}
}
これをコンパイルしようとすると、次のエラーが発生しB
、他の 2 つの型パラメーターについても同様のエラーが発生します。
|
22 | pub fn from<B: BlockFunctionality<T, U> + Send>(b:B) -> Self {
| -- help: consider adding an explicit lifetime bound...: `B: 'static +`
...
27 | let handle:JoinHandle<Result<(), &'static str>> = tokio::spawn(async move {
| ^^^^^^^^^^^^ ...so that the type `impl std::future::Future` will meet its required lifetime bounds
ライフタイムのどこに問題があるのか 理解するのに苦労しています。私が理解しているように、寿命の問題は通常、十分に長く生きていない参照から発生しますが、参照を使用せずに値を移動しています。b
、、rx_input
およびtx_output
をクロージャに移動しtx_input
、、、rx_output
およびをhandle
呼び出しスコープに保持します。この場合、コンパイラを満たす方法を知っている人はいますか?