![](/img/trans.png)
[英]How to create a Rc<RefCell<>> of a self mutable reference?
[英]How to iterate over an Rc<RefCell<T>> that returns raw mutable references
我在结构上有一个Vec<Rc<RefCell<MyStruct>>>
成员,并且我有一个外部库 function 期望被交给一个Iterator
,该迭代器的Item
是&'a mut dyn LibTrait
,我作为其中的成员拥有MyStruct
。 我无法弄清楚如何从迭代器中的Rc<RefCell<MyStruct>>
中获取原始&mut
,即使我知道持有它的Vec
成员会比迭代器或获得的 function 停留更长的时间通过了迭代器。
图书馆看起来像这样:
struct Lib {}
trait LibTrait {
fn run(&mut self);
}
impl Lib {
pub fn lib_func<'a, Iter>(&mut self, trait_iter: Iter)
where
Iter: Iterator<Item = &'a mut dyn LibTrait>,
{
...
}
}
这是我的最新尝试,我尝试创建一个临时 Vec 来将 RefMut 保存到所有 MyStructs,以便在 &mut 将在迭代器和 lib function 内的整个时间内拥有这些 refs。 (此代码抱怨“由于要求冲突,无法推断 function 调用中的生命周期参数的适当生命周期”。)
struct TraitImpl {
dummy: f32,
}
impl LibTrait for TraitImpl {
fn run(&mut self) {
self.dummy += 1.0;
}
}
struct MyStruct {
my_impl: TraitImpl,
num: f32,
}
type MutStructSlice<'a> = &'a mut [&'a mut MyStruct];
struct TraitIterator<'a> {
my_structs: MutStructSlice<'a>,
index: usize,
}
impl<'a> TraitIterator<'a> {
fn new(my_structs: MutStructSlice<'a>) -> Self {
Self {
my_structs,
index: 0,
}
}
}
impl<'a> Iterator for TraitIterator<'a> {
type Item = &'a mut dyn LibTrait;
fn next(&mut self) -> Option<&'a mut dyn LibTrait> {
if self.index >= self.my_structs.len() {
return None;
}
Some(&mut self.my_structs[self.index].my_impl)
}
}
struct Data {
data: Vec<Rc<RefCell<MyStruct>>>,
lib: Lib,
}
impl Data {
fn do_stuff(&mut self) {
let mut struct_refs: Vec<RefMut<MyStruct>> = self
.data
.iter_mut()
.map(|s_rc| s_rc.borrow_mut())
.collect();
let mut structs_raw_refs: Vec<&mut MyStruct> =
struct_refs.iter_mut().map(|s_ref| &mut **s_ref).collect();
self.lib.lib_func(TraitIterator::new(&mut structs_raw_refs));
}
}
这里是游乐场
鉴于我无法更改库并且我需要将 Rc<RefCell<>>'s 用于数据,有没有办法解决这个问题?
我认为你过于复杂了。 您不需要自定义迭代器,您可以使用.map()
执行此操作:
fn do_stuff(&mut self) {
let mut struct_refs: Vec<RefMut<MyStruct>> = self.data
.iter_mut()
.map(|s_rc| s_rc.borrow_mut())
.collect();
self.lib.lib_func(struct_refs.iter_mut().map(|s_ref| &mut s_ref.my_impl as &mut dyn LibTrait));
}
你会得到你所做的错误,因为为&mut T
实现Iterator
本质上是不安全的。 请参阅如何实现生成可变引用的迭代器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.