将切片从静态回调转发到通道时存在冲突的生命周期要求
Conflicting lifetime requirements when forwarding slices from a static callback into a channel
我正在使用 Rust Midi library to receive and handle real-time Midi messages. It exposes a connect
function that accepts a callback which will be called for every Midi message that arrives. My plan was to forward these Midi messages to a channel. This is the minimal version of the code that still reproduces my issue (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
实际上起到了作用。我不知道为什么会这样。
Another question I've found 解释了如何通过通道发送可变切片,但我有不可变切片,所以我认为有比那里解释的更简单的解决方案。
关闭此功能:我知道可以重构代码以避免通道。但是,我仍然对解决方案感兴趣,因此我可以自己解决未来的渠道和回调问题。
它在我的脑海中响起。
此外,对于 move
关键字,以下是必需的:
connect
提供对回调范围内数组的引用。这意味着当回调完成时,&[u8]
是不可访问的。我尝试在回调之外发送引用,这没有任何意义,因为那样它就必须活得更久。
解决方案是从切片创建一个拥有的对象,如 Vec
。通过添加 .to_vec()
:
即可轻松完成
connect(move |data| tx.send(data.to_vec()).unwrap());
Vec
可以自由传递,没有任何生命周期冲突。 :)
我正在使用 Rust Midi library to receive and handle real-time Midi messages. It exposes a connect
function that accepts a callback which will be called for every Midi message that arrives. My plan was to forward these Midi messages to a channel. This is the minimal version of the code that still reproduces my issue (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
实际上起到了作用。我不知道为什么会这样。
Another question I've found 解释了如何通过通道发送可变切片,但我有不可变切片,所以我认为有比那里解释的更简单的解决方案。
关闭此功能:我知道可以重构代码以避免通道。但是,我仍然对解决方案感兴趣,因此我可以自己解决未来的渠道和回调问题。
它在我的脑海中响起。
此外,对于 move
关键字,以下是必需的:
connect
提供对回调范围内数组的引用。这意味着当回调完成时,&[u8]
是不可访问的。我尝试在回调之外发送引用,这没有任何意义,因为那样它就必须活得更久。
解决方案是从切片创建一个拥有的对象,如 Vec
。通过添加 .to_vec()
:
connect(move |data| tx.send(data.to_vec()).unwrap());
Vec
可以自由传递,没有任何生命周期冲突。 :)