2016-01-15 29 views
1

我覺得rc::Weak可以使用(某種)AsRef特徵實現。我想借用一個弱指針一些共享的內容,但是這不會編譯:從弱點借錢<T>

use std::rc::Weak; 

struct Thing<T>(Weak<T>); 


impl<T> Thing<T> { 
    fn as_ref(&self) -> Option<&T> { 
    self.0.upgrade().map(|rc| { 
     rc.as_ref() 
    }) 
    } 

    // For clarity, without a confusing closure 
    fn unwrapped_as_ref(&self) -> &T { 
    self.0.upgrade().unwrap().as_ref() 
    } 
} 

我明白爲什麼:升級Rc不下去了as_ref電話。但在我看來,這聽起來很完美。一個可能的魔術使用unsafe,它編譯:

impl<T> Thing<T> { 
    fn unwrapped_as_ref<'a>(&'a self) -> &'a T { 
    let rc = self.0.upgrade().unwrap(); 
    unsafe { 
     std::mem::transmute(rc.as_ref()) 
    } 
    } 
} 

所以:

  • 有什麼缺點這個解決方案?聽起來不錯嗎?你能想到一個更簡單的替代方案嗎?
  • 在標準庫中實現as_ref(&self) -> Option<&T>是否有意義?
+3

我可能會失去一些至關重要的東西,但在我看來,這聽起來不太可能。只要你的'as_ref'函數退出,升級後的引用就被銷燬了,所以不能保證數據沒有被釋放,你不能引用它。 – kirelagin

回答

3

你不能借用參考,你只是不能。它很弱,它不能保證底層對象存在(這就是爲什麼upgrade()返回Option)。即使您運氣不錯,並且在您通過弱參考(upgrade()返回Some)訪問該值時仍然存活,那麼只要upgrade d參考超出範圍,它就可以在下一時刻釋放。

爲了獲得潛在價值的參考,你需要這會保持它的活力(例如強引用),但這意味着你必須將它和引用一起返回。

+0

你的答案大部分是關於點的,但['upgrade()'](http://doc.rust-lang.org/std/rc/struct.Weak.html#method.upgrade)確實(可能)將'弱「到」Rc「中,所以OP並不試圖」從弱指針借用「。 – Shepmaster

+2

@Shepmaster就我所知,最不想做的事是從弱參考借用。作爲一箇中間步驟,它(可能)轉換爲'Rc',但這不可能有幫助,除非我看不到明顯的東西。 – kirelagin

+0

看起來我最終試圖借鑑一個薄弱的參考。我想我需要做的事情就像'as_ref(&self) - > ThingRef ''我在那裏返回一個類似'ThingRef(Rc )'執行'AsRef '的包裝類型。 – rvidal