#rust #future #lifetime #rust-futures
Вопрос:
У меня есть эта функция, которая выполняет некоторую работу с фьючерсами, созданными вручную.
pub type Response = Pinlt;Boxlt;dyn Futurelt;Output = Resultlt;T, Errorgt;gt; Sendgt;gt; pub fn get_listlt;T: DeserializeOwned Send 'static, P: serde::Serialize Clone Sendgt;( amp;self, path: amp;str, params: P, ) -gt; Responselt;Listlt;Tgt;gt; { use futures::future::FutureExt; let resp: Responselt;Listlt;Tgt;gt; = self.get_query(path, params.clone()); let params = params.clone(); let resp = resp.then(move |res| async move { let params = params; // Take ownership of params. match res { Ok(list) =gt; list.params(amp;params), Err(e) =gt; Err(e), } }); return Box::pin(resp); }
Я получаю сообщение об ошибке:
the parameter type `P` may not live long enough ...so that the type `futures_util::future::Thenlt;Pinlt;Boxlt;dyn futures_util::Futurelt;Output = Resultlt;Listlt;Tgt;, error::Errorgt;gt; std::marker::Sendgt;gt;, impl futures_util::Future, [closure@src/client/async.rs:142:30: 148:10]gt;` will meet its required lifetime bounds
Я не хочу создавать P
статику, но я не против клонирования своего пути к решению. Я понимаю, что использование async move
должно перемещать параметры и брать на себя ответственность, поэтому мне не нужна какая-либо продолжительность жизни на P. Но очевидно, что с жизнями все еще происходит что-то странное.
Есть какие-нибудь предложения?
Ответ №1:
Чтобы это сработало, вам нужно P: 'static
. Прямо сейчас вы клонируете params
, но это не мешает типу P
содержать ссылки , которые в какой-то момент станут недействительными, независимо от того, были ли эти ссылки клонированы. Добавляя P: 'static
привязку, вы P
запрещаете содержать такие ссылки.
P: 'static
может быть прочитано как «значения типа P
могут храниться столько, сколько захочет их владелец». Это не значит, что params
потребуется жить бесконечно, только то, что это возможно.