Это не то, как вы применяете несколько ограничений к параметру типа. Вместо этого вы используете оператор +
, например: <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
, необходимо разыменовать с помощью *
. Это может быть немного сложно в вашем случае, потому что есть одеяло impl
из BorrowMut
, что означает, что 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
был клонирован в курсор. В противном случае он будет перемещен, и вы не сможете использовать его позже.