Rust中如何将回调闭包的数据传递到mpsc通道生产者
错误原因
- 第一个生命周期错误:你定义的
Sender<&[u8]>要求存储的切片引用的生命周期不短于Sender自身的生命周期,但回调参数data:&[u8]是回调被触发时才传入的临时引用,生命周期仅存在于单次回调调用过程中,远短于Sender的生命周期,直接发送该引用必然出现生命周期不匹配问题。 - 第二个
'static要求错误:你使用的回调traitSampleCb要求实现者满足'static生命周期约束,而你的闭包捕获了带非'static生命周期参数的Sender<&[u8]>,导致闭包自身生命周期也绑定了非'static参数,不符合trait要求,这个错误和第一个错误是独立的,即使解决了第一个生命周期问题,只要Sender带非'static参数,这个错误依然存在。
解决方案
最简洁的修复方式是放弃在通道中传递引用,改为传递拥有所有权的Vec<u8>,完全规避生命周期约束:
修改后的完整代码
use std::sync::mpsc::channel; use std::sync::mpsc::Sender; use std::thread; // 把Sender的泛型参数从&[u8]改为Vec<u8> fn init(sender: Sender<Vec<u8>>) { let mut handle_event = |x:i32, data:&[u8]| { // 把临时切片拷贝为拥有所有权的Vec再发送 sender.send(data.to_vec()).unwrap(); }; // 此处注册回调也能满足'static要求,因为捕获的Sender无生命周期参数 // 示例的注册代码:xxx.sample_cb(handle_event); sender.send("Callback registered".as_bytes().to_vec()).unwrap(); } fn main() { let (producer, bottle) = channel(); let child = thread::spawn(move || init(producer)); for message in bottle { // 处理数据,message是Vec<u8>类型,可直接使用,也可转为&[u8] println!("received: {}", String::from_utf8_lossy(&message)); } let _res = child.join(); }
修改说明
- 通道传输类型替换为
Vec<u8>后,传递的是数据的所有权,不存在引用生命周期校验问题,消费者可以任意持有和处理收到的数据 - 回调中收到临时切片时调用
to_vec()拷贝一份数据,拷贝后的数据生命周期和回调传入的临时引用完全解耦,可安全跨线程传递 - 无生命周期参数的
Sender<Vec<u8>>本身满足'static约束,捕获该Sender的闭包自然也符合SampleCb的'static要求,第二个错误也同步解决
内容的提问来源于stack exchange,提问作者Sam Thomas
相关产品推荐
相关产品推荐

