Syntax 在结构类型中包装RefCell和Rc

Syntax 在结构类型中包装RefCell和Rc,syntax,rust,traits,type-bounds,Syntax,Rust,Traits,Type Bounds,我想要一个具有可写字段但可显式借用的结构: struct App<W: Clone<BorrowMut<Write>>> { stdout: W, } 锈皮: error[E0107]:类型参数数量错误:应为0,找到1 -->src/bin/play.rs:6:21 | 6 |结构应用程序{ |^^^^^^^^^^^^^^^^^^^^意外的类型参数 我的最终目标是:将stdin、stdout和stderr传递给App结构。在fn main中,这些将

我想要一个具有可写字段但可显式借用的结构:

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

error[E0107]:类型参数数量错误:应为0,找到1
-->src/bin/play.rs:6:21
|
6 |结构应用程序{
|^^^^^^^^^^^^^^^^^^^^意外的类型参数
我的最终目标是:将
stdin
stdout
stderr
传递给
App
结构。在
fn main
中,这些将是真正的stdin/stdout/stderr。在测试中,这些可能是游标。因为我需要在
App
之外访问它们(例如在测试中),所以我需要多个所有者(因此
Rc
)和运行时可变借用(因此
RefCount


如何实现这一点?

这不是对类型参数应用多个约束的方式。而是使用
+
运算符,如下所示:

但是,如果您想将
RefCell
作为
RefCell
的抽象,它将不起作用。
RefCell
borrow\u mut
方法不是任何特征的一部分,因此您需要在数据结构中直接依赖
RefCell

struct App<W: Clone + Write> {
    stdout: Rc<RefCell<W>>,
}
为了访问
Rc
的内容,您需要使用
*
解除引用。在您的情况下,这可能有点棘手,因为
BorrowMut
有一个覆盖的
impl
,这意味着
Rc
有一个不同的
borrow\u mut
,这是您绝对不想要的

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

另外,请注意,
Rc
已被克隆到光标中。否则它将被移动,您以后无法再次使用它。

您的意思是
W
实现了
Clone
BorrowMut
。因此
RefCell::borrow\u mut
BorrowMut
特征无关。谢谢,这很有效!我还认为可以从W定义中删除
+克隆。
struct App<W: Clone + Write> {
    stdout: Rc<RefCell<W>>,
}
struct App<W> {
    stdout: Rc<RefCell<W>>,
}
impl<W: Clone + Write> App<W> {
    fn hello(&mut self) -> Result<()> {
        (*self.stdout).borrow_mut().write(b"world\n")?;
        Ok(())
    }
}
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);