簡體   English   中英

如何為包含Rc的結構實現Deref <Refcell<Trait> &gt;?

[英]How can I implement Deref for a struct that holds an Rc<Refcell<Trait>>?

我的目標是將針對我的結構的方法調用委托給Trait的方法,其中Trait對象位於RefCellRc中。

我試圖遵循以下問題的建議: 如何從Rc <RefCell <A >>獲取&A參考?

我收到一個編譯錯誤。

use std::rc::Rc;
use std::cell::RefCell;
use std::fmt::*;
use std::ops::Deref;

pub struct ShyObject {
    pub association: Rc<RefCell<dyn Display>>
}

impl Deref for ShyObject {
    type Target = dyn Display;
    fn deref<'a>(&'a self) -> &(dyn Display + 'static) {
        &*self.association.borrow()
    }
}

fn main() {}

這是錯誤:

error[E0515]: cannot return value referencing temporary value
  --> src/main.rs:13:9
   |
13 |         &*self.association.borrow()
   |         ^^-------------------------
   |         | |
   |         | temporary value created here
   |         returns a value referencing data owned by the current function

我的示例使用Display作為特征。 實際上,我有很多方法的特質。 我試圖避免必須實現所有這些方法的樣板,而只是在每個調用中探究Trait對象。

你不能 RefCell::borrow返回Ref<T> ,而不是&T 如果嘗試使用方法來執行此操作,則需要首先借用Ref<T>但它會超出范圍。

除了實現Deref ,您還可以使用一個方法返回執行Deref的方法:

impl ShyObject {
    fn as_deref(&self) -> impl Deref<Target = dyn Display> {
        self.association.borrow()
    }
}

否則,由於無論如何您只想公開內部數據的Display實現,因此可以通過實際取消引用委托的其他類型來解決此問題:

pub struct ShyObject {
    association: Assocation<dyn Display>,
}

struct Assocation<T: ?Sized>(Rc<RefCell<T>>);

impl<T: Display + ?Sized> fmt::Display for Assocation<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0.borrow())
    }
}

impl Deref for ShyObject {
    type Target = dyn Display + 'static;
    fn deref(&self) -> &Self::Target {
        &self.association
    }
}

你不能這樣做。 borrow創建一個新的結構 ,該結構允許RefCell跟蹤借位。 然后,您將不允許向此Ref返回借用,因為它是局部變量。

如何創建 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?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 如何使用 Rc 的數據類型<refcell<t> &gt; 在結構中? </refcell<t> 向下轉換 Rc <refcell<box<struct> &gt;&gt; 到 Rc <refcell<box<dyn trait> &gt;&gt; </refcell<box<dyn></refcell<box<struct> 我如何施放 Rc <refcell<concretetype> &gt; 到 Rc <refcell<dyn trait> &gt;? </refcell<dyn></refcell<concretetype> 如何從 Rc 獲得 &amp;A 參考<RefCell<A> &gt;? 如何創建 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<> 如何在具有生命周期的結構上實現標記特征? 如何為枚舉實現Borrow,ToOwned或Deref? 如何在包含銹特質的泛型類型上實現deref? 將RefCell和Rc包裝為結構類型 如何使用具有 Deref 特征的多態性來獲得可以由事務或連接表示的單個 object?
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM