такая структура с вот таким методом в сторонней либе (клиент для телеги)
pub struct Listener {
...
}
impl Listener {
pub fn on_update_new_message<F>(&mut self, fnc: F) -> &mut Self
where F: Fn((&EventApi, &UpdateNewMessage)) -> TGResult<()> + Send + Sync + 'static
...
}
}
у меня есть вот такая над ней обертка:
pub struct TgClient {
client: Client
}
хочетя докинуть в структуру метод, который вызывал бы listener.on_update_new_message. в примерах из соответствуюшей илибы туда передается closure, но он создается в main'е, так что static-lifetime ок
и хочется, чтобы внутри closure жил mpsc::Sender, которой мог бы эти апдейты принимать и передавать куда-нибудь наружу
собсна, как сделал:
impl TgClient {
fn start_listen_updates(&mut self, channel: Mutex<mpsc::Sender<Update>>) { // mutex, т.к. Sender не реализует Sync
let listener = self.client.listener();
listener.on_update_new_message(get_new_message_handler(channel));
}
}
fn get_new_message_handler(channel: Mutex<mpsc::Sender<Update>>) -> impl Fn((&EventApi, &UpdateNewMessage)) -> TGResult<()> + 'static {
let local = channel.into_inner().unwrap().clone();
move|(api, update)| {
local.send(Update::NewMessage(update.clone())).unwrap();
Ok(())
}
}
компилятор ругается:
50 | listener.on_update_new_message(get_new_message_handler(channel));
| ^^^^^^^^^^^^^^^^^^^^^ `std::sync::mpsc::Sender<rtdlib::types::update::Update>` cannot be shared between threads safely
...
149 | fn get_new_message_handler(channel: Mutex<mpsc::Sender<Update>>) -> impl Fn((&EventApi, &UpdateNewMessage)) -> TGResult<()> + 'static {
| ----------------------------------------------------------------- within this `impl for<'r, 's> std::ops::Fn<((&'r telegram_client::api::aevent::EventApi, &'s rtdlib::types::update::UpdateNewMessage),)>`
существует ли решение? или канал не вариант и надо как-то через lazy_static всё делать с обработкой апдейтов непосредственно внутри замыкания?
>но он создается в main'е, так что static-lifetime Нет, у всего, что создаётся внутри мейн функции лайфтайм не статик.
и правда. тогда почему это работает?.. fn main() { ... let listener = client.listener(); listener.on_update_option(|(api, option)| { ... }) } impl Listener { pub fn on_update_option<F>(&mut self, fnc: F) -> &mut Self where F: Fn((&EventApi, &UpdateOption)) -> TGResult<()> + Send + Sync + 'static { ... } }
Потому что если кложура не ловит окружение, у неё нет лайфтайма и её можно заборровить на 'static.
Обсуждают сегодня