简体   繁体   English

使用内部可变性模式的“BorrowMutError”

[英]“BorrowMutError” using the Interior Mutability Pattern

I am trying to use the Interior Mutability Pattern to share mutable reference.我正在尝试使用内部可变性模式来共享可变引用。

However, when I try to use the reference from the structs it is shared with, the program panics with the error:但是,当我尝试使用与它共享的结构中的引用时,程序会因错误而恐慌:

thread 'main' panicked at 'already borrowed: BorrowMutError'

Here is the code:这是代码:

use std::rc::Rc;
use std::cell::RefCell;

fn main() {
    let game = Game::init();
    game.start();
}

struct Game {
    ecs: Rc<RefCell<Ecs>>,
}

impl Game {
    pub fn init() -> Game {
        let ecs = Rc::new(RefCell::new(Ecs::new()));
        ecs.borrow_mut().register_systems(vec![
            Box::new(Renderer {
                ecs: Rc::clone(&ecs),
            }),
        ]);
        Game {
            ecs: Rc::clone(&ecs),
        }
    }

    pub fn start(&self) {
        self.ecs.borrow_mut().update();
    }
}

struct Ecs {
    systems: Vec<Box<dyn System>>,
}

impl Ecs {
    fn new() -> Ecs {
        Ecs {
            systems: vec![],
        }
    }

    fn register_systems(&mut self, systems: Vec<Box<dyn System>>) {
        self.systems = systems;
    }

    fn update(&self) {
        for system in self.systems.iter() {
            system.update();
        }
    }

    fn test(&self) {
        println!("done!");
    }
}

trait System {
    fn update(&self);
}


struct Renderer {
    ecs: Rc<RefCell<Ecs>>,
}

impl System for Renderer {
    fn update(&self) {
        self.ecs.borrow_mut().test();
    }
}

The issue seems to be at the line:问题似乎出在这一行:

self.ecs.borrow_mut().test();

What's the problem here?这里有什么问题? Is it related to the trait?跟性格有关系吗? Or do I need to call the function test in anoher way?还是我需要以另一种方式调用函数test

Indeed, the ecs member in Renderer is a clone of the ecs member in Game , ie they both own the same Ecs .事实上, ecs成员在Renderer是一个克隆ecs会员Game ,即它们都拥有相同的Ecs

When you borrow_mut() the ecs member in Game then iterate on the elements, you reach the Renderer which borrow_mut() s the same Ecs .当您对Gameecs成员borrow_mut()然后对元素进行迭代时,您会到达borrow_mut()Ecs相同的Renderer This is detected at runtime and then panics, which the intended behaviour of RefCell .这是在运行时检测到的,然后恐慌,这是RefCell的预期行为。

If you just change borrow_mut() to borrow() in both cases, this does not panic any more since multiple immutable borrows are allowed.如果你只需要改变borrow_mut()borrow()在这两种情况下,这并不惊慌任何更多,因为多个不变借力是允许的。

I don't know exactly the purpose of this code but I'm not certain that borrowing the Ecs as whole from Renderer is a good idea.我不知道这段代码的确切用途,但我不确定从Renderer整体借用Ecs是个好主意。 I would presume that the interior-mutability should apply to each stored component individually rather than to the whole Ecs .我认为内部可变性应该单独应用于每个存储的组件而不是整个Ecs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM