Rust 如何从带有';静态边界?
我正在使用库,并试图从函数中获取一系列的:Rust 如何从带有';静态边界?,rust,closures,lifetime,Rust,Closures,Lifetime,我正在使用库,并试图从函数中获取一系列的: pub fn get_sink_input_info_list<F>( &self, callback: F, ) -> Operation<dyn FnMut(ListResult<&SinkInputInfo>)> where F: FnMut(ListResult<&SinkInputInfo>) + 'static, 然而,这似乎不起作用。我
pub fn get_sink_input_info_list<F>(
&self,
callback: F,
) -> Operation<dyn FnMut(ListResult<&SinkInputInfo>)>
where
F: FnMut(ListResult<&SinkInputInfo>) + 'static,
然而,这似乎不起作用。我有以下代码:
let mut sink_infos: Vec<StreamInfo> = Vec::new();
let op = introspector.get_sink_input_info_list(|result| match result {
pulse::callbacks::ListResult::Item(info) => sink_infos.push(info.into()),
pulse::callbacks::ListResult::End => {},
pulse::callbacks::ListResult::Error => panic!("Error getting sink input info"),
});
tldr:闭包必须有静态的生存期,因为libpulse\u binding这么说(大概是因为它被交给了PulseAudio C API,然后它可以对它做任何它喜欢的事情),但是sink\u infos
不是静态的,闭包必须借用sink\u infos
才能附加到它,这使得闭包不是静态的,IIUC
如果给定一个使用&SinkInputInfo
重复调用的'static
闭包,我如何创建Vec
(或任何容器,我不挑剔)的SinkInputInfo
给定一个对象T
,只能具有以下其中一项:
use std::cell::RefCell;
use std::rc::Rc;
let sink_infos: Rc<RefCell<Vec<StreamInfo>>> = Rc::new(RefCell::new(Vec::new()));
let sink_infos2 = sink_infos.clone(); // Create a new Rc which points to the same data.
let op = introspector.get_sink_input_info_list(move |result| match result {
pulse::callbacks::ListResult::Item(info) => sink_infos2.borrow_mut().push(info.into()),
pulse::callbacks::ListResult::End => {},
pulse::callbacks::ListResult::Error => panic!("Error getting sink input info"),
});
- 对对象有几个不可变的引用(
&T
)(也称为别名)
- 对对象有一个可变引用(
&mut
)(也称为可变性)
您正试图保留对您的Vec的引用&Vec
(以便以后使用),同时尝试在闭包中向其添加内容(即&mut-Vec
)。Rust不知道当闭包使用&mut-Vec
时,您不会尝试使用&Vec
,因此它不允许您在闭包中创建&mut-Vec
,而闭包外仍有&Vec
挂起
你能做的下一件最好的事情就是使用一个。这将允许您避开编译器的借用检查,而将其推迟到运行时。但是:这意味着,如果您试图在程序运行时违反借用规则,它将死机,而不是编译时错误
在大多数情况下,您可以将Rc
视为正常的Vec
,因为Rc
实现Deref
由于您还希望能够对Vec
进行变异,以便向其添加内容,因此您还需要将其放在一个特定的位置。这将在Vec
周围设置一个锁,确保您一次只能有一个&mut-Vec
,并且如果您有&Vec
,您就不能有&mut-Vec
(同样,如果您试图违反规则,您的程序将死机)。您可以使用RefCell
上的.borrow()
和.borrow_mut()
方法来获取对Vec的共享和可变引用(如果您可以在无法进行借用时采取合理的措施,也可以使用这些方法的try*
变体)
如果不使用RefCell
,则只能从Rc
获取不可变/共享引用(&Vec
)(除非您只有一个Rc
,但这样您就不需要Rc
!)
请尝试以下操作:
use std::cell::RefCell;
use std::rc::Rc;
let sink_infos: Rc<RefCell<Vec<StreamInfo>>> = Rc::new(RefCell::new(Vec::new()));
let sink_infos2 = sink_infos.clone(); // Create a new Rc which points to the same data.
let op = introspector.get_sink_input_info_list(move |result| match result {
pulse::callbacks::ListResult::Item(info) => sink_infos2.borrow_mut().push(info.into()),
pulse::callbacks::ListResult::End => {},
pulse::callbacks::ListResult::Error => panic!("Error getting sink input info"),
});
使用std::cell::RefCell;
使用std::rc::rc;
让sink_infos:Rc=Rc::new(RefCell::new(Vec::new());
让sink_infos2=sink_infos.clone();//创建指向相同数据的新Rc。
让op=内省者。获取_sink_input_info_列表(移动|结果|匹配结果{
pulse::callbacks::ListResult::Item(info)=>sink_infos2.borrow_mut().push(info.into()),
pulse::callbacks::ListResult::End=>{},
pulse::callbacks::ListResult::Error=>panic!(“获取接收器输入信息时出错”),
});
你同意这是重复的吗?@Shepmaster看起来基本上是同一个问题,是的–我只能假设我没有找到正确的东西来找到它。谢谢