我尝试从Heads-up Design Patterns 中实现观察者模式,它最初是用 Java 编写的:
use std::cell::RefCell;
use std::rc::Rc;
use std::borrow::BorrowMut;
trait Subject {
fn registerObserver(&mut self, observer: Rc<RefCell<Observer>>);
fn removeObserver(&mut self, observer: Rc<RefCell<Observer>>);
fn notifyObserver(&self, observer: Rc<RefCell<Observer>>);
}
trait Observer {
fn update(&mut self, data: f32);
}
struct Teacher {
observers: Vec<Rc<RefCell<Observer>>>,
data: f32,
}
impl Teacher {
pub fn print(&self) {
println!("teacher = {:}", self.data);
}
}
impl Subject for Teacher {
fn registerObserver(&mut self, observer: Rc<RefCell<Observer>>) {
self.observers.push(observer);
}
fn removeObserver(&mut self, observer: Rc<RefCell<Observer>>) {
println!("Teacher.removeObserver(...) not implemented yet...")
}
fn notifyObserver(&self, observer: Rc<RefCell<Observer>>) {
for observer in self.observers {
let mut loc_obs = observer.borrow_mut();
loc_obs.update(self.data);
}
}
}
struct Student {
data: f32,
}
impl Student {
pub fn print(&self) {
println!("student = {:}", self.data);
}
}
impl Observer for Student {
fn update(&mut self, data: f32) {
self.data = data;
}
}
fn main() {
let mut teacher = Teacher {
observers: Vec::new(),
data: 42.,
};
teacher.print();
}
Run Code Online (Sandbox Code Playgroud)
编译器告诉我
use std::cell::RefCell;
use std::rc::Rc;
use std::borrow::BorrowMut;
trait Subject {
fn registerObserver(&mut self, observer: Rc<RefCell<Observer>>);
fn removeObserver(&mut self, observer: Rc<RefCell<Observer>>);
fn notifyObserver(&self, observer: Rc<RefCell<Observer>>);
}
trait Observer {
fn update(&mut self, data: f32);
}
struct Teacher {
observers: Vec<Rc<RefCell<Observer>>>,
data: f32,
}
impl Teacher {
pub fn print(&self) {
println!("teacher = {:}", self.data);
}
}
impl Subject for Teacher {
fn registerObserver(&mut self, observer: Rc<RefCell<Observer>>) {
self.observers.push(observer);
}
fn removeObserver(&mut self, observer: Rc<RefCell<Observer>>) {
println!("Teacher.removeObserver(...) not implemented yet...")
}
fn notifyObserver(&self, observer: Rc<RefCell<Observer>>) {
for observer in self.observers {
let mut loc_obs = observer.borrow_mut();
loc_obs.update(self.data);
}
}
}
struct Student {
data: f32,
}
impl Student {
pub fn print(&self) {
println!("student = {:}", self.data);
}
}
impl Observer for Student {
fn update(&mut self, data: f32) {
self.data = data;
}
}
fn main() {
let mut teacher = Teacher {
observers: Vec::new(),
data: 42.,
};
teacher.print();
}
Run Code Online (Sandbox Code Playgroud)
我的错误在哪里?
Run Code Online (Sandbox Code Playgroud)use std::borrow::BorrowMut;
您引入了 trait BorrowMut,它定义了 trait 方法BorrowMut::borrow_mut,隐藏了固有方法RefCell::borrow_mut。您可以这么说是因为您的类型不是您所期望的:
对于类型
&mut std::rc::Rc<std::cell::RefCell<Observer + 'static>>
最简单的解决方法是删除该导入。您还可以消除它们之间的歧义。
然后,您在尝试获取借用值的所有权和许多非惯用名称时会遇到更多问题,这些名称会产生大量警告。你应该解决所有这些问题。