繁体   English   中英

如何创建 Rc <refcell< to something that already exists?< div><div id="text_translate"><p> 因此,为了自学一些 Rust,我决定创建一个我喜欢的简单混合数据类型 ChainVec。 这是一个向量的双向链接列表,如果您需要调整可能增长到巨大规模的向量的大小,这很有用。 它使用链表逻辑,但查找、搜索和迭代特性要快得多,因为它们的增长时间为 O(n/alot)。 不过,这并不是重点:我遇到的问题会出现在任何双向链表中。</p><p> 这就是问题所在......在 C 中,当我创建新的链表节点时,我可以将其“尾部”设置为指向前一个节点的指针。 我可以在 C 中像糖果一样扔指针,但在 Rust 中,我还不知道如何创建新指针。 这是我尝试过的...(在 fn push_head 下查找无效行)</p><p> 注意:在我的实现中,chainvec 的“头”节点是您选择指向的任何一个,因此列表头/尾没有单独的结构。</p><pre> #[allow(non_snake_case)] use std::{cell::RefCell, rc::Rc}; #[allow(dead_code)] struct ChainVec&lt;T&gt; { item: Option&lt;Vec&lt;T&gt;&gt;, head: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, tail: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, } impl&lt;T&gt; ChainVec&lt;T&gt; { fn new(prealloc: usize) -&gt; Self { let vector: Vec&lt;T&gt; = Vec::with_capacity(prealloc); Self { item: Some(vector), head: None, tail: None, } } fn new_with_links(prealloc: usize, head: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;, tail: Option&lt;Rc&lt;RefCell&lt;ChainVec&lt;T&gt;&gt;&gt;&gt;) -&gt; Self { let vector: Vec&lt;T&gt; = Vec::with_capacity(prealloc); Self { item: Some(vector), head: head, tail: tail, } } fn push_head(&amp;mut self, prealloc: usize) { self.head = Some(Rc::new(RefCell::new(ChainVec::new_with_links(prealloc, None, Some(Rc::new(RefCell::new(self))))))); } } #[allow(unused_variables)] fn main() { let alef: ChainVec&lt;u32&gt; = ChainVec::new(100); println,("Hello; world!"); }</pre><p> 显然,当我尝试通过 Some(Rc::new(RefCell::new(self))) 在 push_head 中创建一个新指针时,我迷路了。 我有</p><pre>mismatched types expected struct `ChainVec&lt;T&gt;` found mutable reference `&amp;mut ChainVec&lt;T&gt;`</pre><p> 取消引用运算符在这里不做任何事情......我不知道如何继续。</p><p> 如何创建对已经存在的结构的 Rc&lt;RefCell&lt; 引用? </p></div></refcell<>

[英]How can I create an Rc<RefCell< to something that already exists?

因此,为了自学一些 Rust,我决定创建一个我喜欢的简单混合数据类型 ChainVec。 这是一个向量的双向链接列表,如果您需要调整可能增长到巨大规模的向量的大小,这很有用。 它使用链表逻辑,但查找、搜索和迭代特性要快得多,因为它们的增长时间为 O(n/alot)。 不过,这并不是重点:我遇到的问题会出现在任何双向链表中。

这就是问题所在......在 C 中,当我创建新的链表节点时,我可以将其“尾部”设置为指向前一个节点的指针。 我可以在 C 中像糖果一样扔指针,但在 Rust 中,我还不知道如何创建新指针。 这是我尝试过的...(在 fn push_head 下查找无效行)

注意:在我的实现中,chainvec 的“头”节点是您选择指向的任何一个,因此列表头/尾没有单独的结构。

#[allow(non_snake_case)]
use std::{cell::RefCell, rc::Rc};

 
#[allow(dead_code)]
struct ChainVec<T> {
  item: Option<Vec<T>>,
  head: Option<Rc<RefCell<ChainVec<T>>>>,
  tail: Option<Rc<RefCell<ChainVec<T>>>>,
}


impl<T> ChainVec<T> {
  fn new(prealloc: usize) -> Self {
    let vector: Vec<T> = Vec::with_capacity(prealloc);
        Self {
        item: Some(vector),
        head: None,
        tail: None,
    }
  }

  fn new_with_links(prealloc: usize, 
    head: Option<Rc<RefCell<ChainVec<T>>>>, 
    tail: Option<Rc<RefCell<ChainVec<T>>>>) -> Self {
    let vector: Vec<T> = Vec::with_capacity(prealloc);
        Self {
        item: Some(vector),
        head: head,
        tail: tail,
    }
  }
 fn push_head(&mut self, prealloc: usize) {
    self.head = Some(Rc::new(RefCell::new(ChainVec::new_with_links(prealloc, None, Some(Rc::new(RefCell::new(self)))))));

    }
}

#[allow(unused_variables)]
fn main() {
  let alef: ChainVec<u32> = ChainVec::new(100);
  println!("Hello, world!");
}

显然,当我尝试通过 Some(Rc::new(RefCell::new(self))) 在 push_head 中创建一个新指针时,我迷路了。 我有

mismatched types
        expected struct `ChainVec<T>`
found mutable reference `&mut ChainVec<T>`

取消引用运算符在这里不做任何事情......我不知道如何继续。

如何创建对已经存在的结构的 Rc<RefCell< 引用?

简单的回答:你不能。

一旦您进入将&self&mut self作为参数的 function 内部,function 就不知道它被包裹在Rc中。 所以你不能从它创建一个新的Rc

如果可以的话,现有的Rc和新的Rc怎么知道 object 的存活时间,以及何时删除它?

您只能从现有的 Rc 创建一个新的Rc 这意味着,如果你想实现这一点,你需要将现有的Rc作为参数而不是&self


作为其他图书馆如何处理这个问题的一个外传:

tokio_util::sync::CancellationToken也有类似的问题。 它的解决方法是将Rc隐藏在.inner成员中,然后在对其进行操作时,将整个Arc传递给处理方法。

例如,您可以在clone()上看到这一点,它几乎完全符合您的要求:它在其上运行一些代码并创建一个新的Arc 可以看到它是如何将整个Arc传递到tree_node:: function; tree_node mod 非常类似于在Arc上运行的成员函数的集合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM