首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rc::new_cyclic -借用可能未初始化的变量

Rc::new_cyclic -借用可能未初始化的变量
EN

Stack Overflow用户
提问于 2022-07-19 17:43:28
回答 1查看 67关注 0票数 0

我有这个Emulator课程。

代码语言:javascript
复制
pub struct Emulator {
    cart: Rc<RefCell<Cartridge>>,
    bus: Rc<RefCell<Bus>>, /* requirs access to cartridge, dma, ppu, and joypad */
    cpu: Rc<RefCell<M6502>>, /* requires access to bus */
    ppu: Rc<RefCell<PPU>>, /* requires access to cartridge */
    dma: Rc<RefCell<DMA>>, /* requires access to cpu, ppu, and bus */
    joypad: Rc<RefCell<Joypad>>
}

您可以看到,它的组件相互依赖。我决定使用RcWeak来维护这种循环关系。

我很难弄清楚如何创建这个结构的新实例。

代码语言:javascript
复制
impl Emulator {
    pub fn new(fname: &str) -> Self {
        let cart_ref = Rc::new(RefCell::new(Cartridge::new(fname)));
        let weak_cart = Rc::downgrade(&cart_ref);

        let ppu_ref = Rc::new(RefCell::new(PPU::new(weak_cart.clone())));
        let weak_ppu = Rc::downgrade(&ppu_ref);

        let joypad_ref = Rc::new(RefCell::new(Joypad::new()));
        let weak_joypad = Rc::downgrade(&joypad_ref);

        let mut bus_ref: Rc<RefCell<Bus>>;
        let mut cpu_ref: Rc<RefCell<M6502>>;

        let dma_ref = Rc::new_cyclic(|weak_dma| {
            bus_ref = Rc::new(RefCell::new(Bus::new(
                weak_cart.clone(),
                weak_ppu.clone(),
                weak_joypad.clone(),
                weak_dma.clone()
            )));
            let weak_bus = Rc::downgrade(&bus_ref);

            cpu_ref = Rc::new(RefCell::new(M6502::new(weak_bus.clone())));
            let weak_cpu = Rc::downgrade(&cpu_ref);

            RefCell::new(DMA::new(weak_cpu.clone(), weak_ppu.clone(), weak_bus.clone()))
        });

        Emulator {
            cart: cart_ref,
            bus: bus_ref,
            cpu: cpu_ref,
            ppu: ppu_ref,
            dma: dma_ref,
            joypad: joypad_ref
        }
    }
    ...
}

我犯了这个错误

代码语言:javascript
复制
error[E0381]: borrow of possibly-uninitialized variable: `bus_ref`
  --> src\emulator.rs:38:38
   |
38 |         let dma_ref = Rc::new_cyclic(|weak_dma| {
   |                                      ^^^^^^^^^^ use of possibly-uninitialized `bus_ref`
39 |             bus_ref = Rc::new(RefCell::new(Bus::new(
   |             ------- borrow occurs due to use in closure

error[E0381]: borrow of possibly-uninitialized variable: `cpu_ref`
  --> src\emulator.rs:38:38
   |
38 |         let dma_ref = Rc::new_cyclic(|weak_dma| {
   |                                      ^^^^^^^^^^ use of possibly-uninitialized `cpu_ref`
...
47 |             cpu_ref = Rc::new(RefCell::new(M6502::new(weak_bus.clone())));
   |             ------- borrow occurs due to use in closure

我不知道怎么修好它。我想不出其他的组合。我想知道我是否应该重组我的代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-19 18:23:35

您不能在闭包中借用未初始化的变量,因为当它被删除时,编译器必须知道它是否已初始化,但它无法跟踪闭包内的变量(不是完全不能,但无论如何,这是Rust不支持的)。见第41124期

我处理这个问题的方法是在这里和那里洒一些Options和.unwrap()s:

代码语言:javascript
复制
let mut bus_ref: Option<Rc<RefCell<Bus>>> = None;
let mut cpu_ref: Option<Rc<RefCell<M6502>>> = None;

let dma_ref = Rc::new_cyclic(|weak_dma| {
    let bus_ref_ = Rc::new(RefCell::new(Bus::new(
        weak_cart.clone(),
        weak_ppu.clone(),
        weak_joypad.clone(),
        weak_dma.clone(),
    )));
    let weak_bus = Rc::downgrade(&bus_ref_);

    let cpu_ref_ = Rc::new(RefCell::new(M6502::new(weak_bus.clone())));
    let weak_cpu = Rc::downgrade(&cpu_ref_);

    bus_ref = Some(bus_ref_);
    cpu_ref = Some(cpu_ref_);

    RefCell::new(DMA::new(
        weak_cpu.clone(),
        weak_ppu.clone(),
        weak_bus.clone(),
    ))
});

Emulator {
    cart: cart_ref,
    bus: bus_ref.unwrap(),
    cpu: cpu_ref.unwrap(),
    ppu: ppu_ref,
    dma: dma_ref,
    joypad: joypad_ref,
}

不完美,但有效。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73041372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档