【问题标题】:items from traits can only be used if the trait is implemented and in scope只有在实现了 trait 并且在范围内时,才能使用来自 trait 的项目
【发布时间】:2025-12-02 18:05:01
【问题描述】:

我尝试从 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();
}

Playground

编译器告诉我

error[E0599]: no method named `update` found for type `&mut std::rc::Rc<std::cell::RefCell<Observer + 'static>>` in the current scope
  --> src/main.rs:35:21
   |
35 |             loc_obs.update(self.data);
   |                     ^^^^^^
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `update`, perhaps you need to implement it:
           candidate #1: `Observer`

我的错误在哪里?

【问题讨论】:

    标签: scope rust traits


    【解决方案1】:
    use std::borrow::BorrowMut;
    

    你引入了 trait BorrowMut,它定义了 trait 方法 BorrowMut::borrow_mutshadowing 固有方法 RefCell::borrow_mut。你可以这么说,因为你的类型不是你所期望的:

    对于类型&amp;mut std::rc::Rc&lt;std::cell::RefCell&lt;Observer + 'static&gt;&gt;

    最简单的解决方法是删除该导入。你也可以disambiguate between them

    然后,您在尝试获取借用值的所有权和大量非惯用名称时会遇到更多问题,这些名称会产生大量警告。你应该解决所有这些问题。

    【讨论】:

    • 哈哈,比你好多了!我自动导入了 BorrowMut... 可能是个坏主意。我应该更加小心!我现在也可以通过将for observer in self.observers 替换为for observer in &amp;self.observers 来实现它。再次感谢!