【问题标题】:Is it possible to call a parent struct's methods from a child struct? [duplicate]是否可以从子结构调用父结构的方法? [复制]
【发布时间】:2020-04-09 08:38:06
【问题描述】:

我正在尝试将对 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();
}

Rust Playground

这个错误:

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++ 中通过从BUS 传入this 然后在connect_bus 中使用*bus 来实现这一点,这样read_ram 就可以是*bus-&gt;read(...)

是否可以从 CPU 结构上的方法调用 BUS 结构的 readwrite 函数?

【问题讨论】:

标签: rust


【解决方案1】:

简短的回答是否定的。

  1. RefCell 拥有它的内部对象。这意味着它拥有该对象的唯一副本,因此它可以完全控制对其的所有访问,并且不允许来自外部的任何其他访问。一个对象不能同时存在于RefCellRefCell 之外。

    您的setup 可以采用现有的Rc&lt;RefCell&lt;BUS&gt;&gt; 并传递它。 &amp;mut BUS 没有包装是不行的。

  2. 借用检查器无法确保相互父子关系的安全。它希望程序数据结构为树或 DAG。否则,您将不得不使用包装类型或类似 C 的原始指针。

借用检查器检查的是接口,而不是实现。如果你的 setter 借用了&amp;mut self,那就是对整个对象的独占借用,对于借用检查,这是最严格和最不灵活的选择。您将需要剥离一些抽象层才能完成这项工作,例如将RAM向下传递给CPU。或者,使 RAM 使用 Cell&lt;u8&gt; 类型,以便可以通过共享引用对其进行变异。

【讨论】:

    猜你喜欢
    • 2014-02-10
    • 2023-03-20
    • 2015-06-22
    • 2015-06-06
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多