簡體   English   中英

如何遍歷 Rc <refcell<t> &gt; 返回原始可變引用</refcell<t>

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM