我试图将对self的引用传递给作为字段变量的子结构
use std::cell::RefCell;
use std::rc::Rc;
pub struct BUS {
pub processor: CPU,
pub ram: [u8; 65536],
}
impl BUS {
pub fn new() -> BUS {
BUS {
processor: CPU::new(),
ram: [0; 65536],
}
}
pub fn setup(&mut self) {
self.processor.connect_bus(Rc::new(RefCell::new(self)));
self.ram.iter_mut().for_each(|x| *x = 00);
}
pub fn write(&mut self, addr: u16, data: u8) {
self.ram[addr as usize] = data;
}
pub fn read(&mut self, addr: u16, _read_only: bool) -> u8 {
self.ram[addr as usize]
}
}
pub struct CPU {
bus_ptr: Rc<RefCell<BUS>>,
}
impl CPU {
pub fn new() -> CPU {
CPU {
bus_ptr: Rc::new(RefCell::new(BUS::new())),
}
}
pub fn connect_bus(&mut self, r: Rc<RefCell<BUS>>) {
self.bus_ptr = r;
}
pub fn read_ram(&self, addr: u16, _read_only: bool) -> u8 {
(self.bus_ptr.borrow_mut().read(addr, false))
}
pub fn write_ram(&mut self, addr: u16, data: u8) {
(self.bus_ptr.borrow_mut().write(addr, data))
}
}
fn main() {
let comp = BUS::new();
comp.setup();
}
此错误:
error[E0308]: mismatched types
--> src/main.rs:18:57
|
18 | self.processor.connect_bus(Rc::new(RefCell::new(self)));
| ^^^^ expected struct `BUS`, found &mut BUS
|
= note: expected type `BUS`
found type `&mut BUS`
我无法将self
传递给RefCell
,因为这是第二次可变借用。我通过移动函数来解决这个问题,但是想知道这种结构的可能性。
我在C ++中实现了这一点,方法是从this
传入BUS
,然后在*bus
中使用connect_bus
,这样read_ram
就可以成为*bus->read(...)
是否可以从CPU结构上的方法调用BUS结构的read
和write
函数?
答案 0 :(得分:3)
简短的回答是“否”。
RefCell
拥有其内部对象。这意味着它拥有该对象的唯一副本,因此它可以完全控制对它的所有访问,并且不允许外部的任何其他访问。对象不能同时存在于RefCell
和RefCell
之外。
您的setup
可以改用现有的Rc<RefCell<BUS>>
并传递它。没有包装的&mut BUS
不会。
借阅检查器不能确保父母与子女之间相互关系的安全。它希望将程序数据构造为树或DAG。否则,您将不得不使用包装器类型或类似C的原始指针。
借位检查器将根据接口而不是实现进行检查。如果您的设置者借用了&mut self
,那是整个对象的专有借用,对于借阅检查,这是最严格,最不灵活的选择。您需要剥离一些抽象层才能完成这项工作,例如将RAM传递给CPU。或者,使RAM使用Cell<u8>
类型,以便可以通过共享引用对其进行突变。