簡體   English   中英

將RefCell和Rc包裝為結構類型

[英]Wrapping RefCell and Rc in a struct type

我想要一個具有可寫字段但可顯式借用的結構:

struct App<W: Clone<BorrowMut<Write>>> {
    stdout: W,
}

...因此它可以在內部使用它:

impl<W: Clone<BorrowMut<Write>>> App<W> {
    fn hello(&mut self) -> Result<()> {
        Rc::clone(&self.stdout).borrow_mut().write(b"world\n")?;
        Ok(())
    }
}

我試圖向它傳遞一個光標,然后使用它:

let mut cursor = Rc::new(RefCell::new(Cursor::new(vec![0])));
let mut app = App { stdout: cursor };
app.hello().expect("failed to write");

let mut line = String::new();
Rc::clone(&cursor).borrow_mut().read_line(&mut line).unwrap();

銹皮:

error[E0107]: wrong number of type arguments: expected 0, found 1
 --> src/bin/play.rs:6:21
  |
6 | struct App<W: Clone<BorrowMut<Write>>> {
  |                     ^^^^^^^^^^^^^^^^ unexpected type argument

我的最終目標是:將stdinstdoutstderr傳遞給App結構。 fn main ,這些將是真實的stdin / stdout / stderr。 在測試中,這些可能是游標。 由於我需要在App外部(例如在測試中)訪問這些文件,因此我需要多個所有者(因此Rc )和運行時可變借用(因此RefCount )。

我該如何實施?

這不是將多個約束應用於類型參數的方式。 而是使用+運算符,如下所示: <W: Clone + Write + BorrowMut>

但是,如果你想BorrowMut成為一個抽象RefCell ,它不會工作。 borrow_mut的方法RefCell沒有任何特質,所以你將需要依賴於部分RefCell直接在你的數據結構:

struct App<W: Clone + Write> {
    stdout: Rc<RefCell<W>>,
}

話雖如此,不對結構施加不必要的約束被認為是最佳實踐。 您實際上可以將其保留在此處,並在稍后的impl提及它們。

struct App<W> {
    stdout: Rc<RefCell<W>>,
}

為了訪問Rc的內容,您需要使用*取消引用。 這可能是你的情況有點棘手,因為有一個毯子implBorrowMut ,這意味着Rc不同的 borrow_mut ,你絕對不希望。

impl<W: Clone + Write> App<W> {
    fn hello(&mut self) -> Result<()> {
        (*self.stdout).borrow_mut().write(b"world\n")?;
        Ok(())
    }
}

同樣,使用此方法時,需要取消引用Rc

let cursor = Rc::new(RefCell::new(Cursor::new(vec![0])));
let mut app = App { stdout: cursor.clone() };
app.hello().expect("failed to write");

let mut line = String::new();

let mut cursor = (&*cursor).borrow_mut();
// move to the beginning or else there's nothing to read
cursor.set_position(0);
cursor.read_line(&mut line).unwrap();

println!("result = {:?}", line);

另外,請注意, Rc已克隆到光標中。 否則它將被移動,您以后將無法再使用。

暫無
暫無

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

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