172 похожих чатов

Немношк плавятся мозги. буду очень благодарен за помощь. итак, есть вот

такая структура с вот таким методом в сторонней либе (клиент для телеги)
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 всё делать с обработкой апдейтов непосредственно внутри замыкания?

3 ответов

22 просмотра

>но он создается в main'е, так что static-lifetime Нет, у всего, что создаётся внутри мейн функции лайфтайм не статик.

antuan- Автор вопроса
Эрик
>но он создается в 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 { ... } }

antuan
и правда. тогда почему это работает?.. fn main() {...

Потому что если кложура не ловит окружение, у неё нет лайфтайма и её можно заборровить на 'static.

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Ребят в СИ можно реализовать ООП?
Николай
33
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
2
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Карта сайта