Я использую библиотеку Rust Midi для получения и обработки сообщений Midi в реальном времени.Он предоставляет функцию connect
, которая принимает обратный вызов, который будет вызываться для каждого поступающего сообщения Midi.Мой план состоял в том, чтобы направить эти сообщения Midi на канал.Это минимальная версия кода, которая все еще воспроизводит мою проблему ( Rust Playground link ):
use std::sync::mpsc;
fn main() {
let (tx, rx) = mpsc::sync_channel(0);
// The callback forwards all data it gets to the channel
connect(|data| tx.send(data).unwrap());
// `rx` will be given to some other part of the program here
}
// This is basically the function signature of my Midi library's `connect` function
// I *don't have control over it*, as it's part of that external library
fn connect<F>(callback: F)
where F: FnMut(&[u8]) + Send + 'static {}
После изучения этой проблемы некоторое время я думал, что решение было добавитьmove
ключевое слово для обратного вызова.Это имело смысл для меня, так как обратный вызов может жить дольше, чем основная функция, поэтому tx
мог быть отброшен, когда обратный вызов все еще нуждается в нем.move
заставляет обратный вызов захватить его окружение по значению, которое должно привести к тому, что tx
будет жить ровно столько же времени, сколько обратный вызов.И все же move
вообще ничего не меняет;сообщение об ошибке остается прежним.
Я заметил, что когда я изменяю параметр обратного вызова с &[u8]
на просто u8
, move
на самом деле делает свое дело.Я понятия не имею, почему это может быть.
Другой вопрос, который я нашел объясняет, как отправлять изменяемые фрагменты по каналам, но у меня есть неизменяемые фрагменты, поэтому я предполагаю, что есть более простое решениечем тот, который был объяснен там.
Чтобы закрыть это: я знаю, что можно реструктурировать код, чтобы избежать каналов.Тем не менее, я все еще заинтересован в решении, поэтому я могу решить будущие проблемы с каналами и обратными вызовами самостоятельно.