"BorrowMutError" 使用内部可变性模式
"BorrowMutError" using the Interior Mutability Pattern
我正在尝试使用内部可变性模式来共享可变引用。
但是,当我尝试使用与其共享的结构中的引用时,程序出现错误并出现混乱:
thread 'main' panicked at 'already borrowed: BorrowMutError'
代码如下:
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();
}
}
问题似乎在以下行:
self.ecs.borrow_mut().test();
这里有什么问题?跟性格有关系吗?还是我需要以其他方式调用函数 test
?
确实,Renderer
中的 ecs
成员是 ecs
成员的克隆
在 Game
,即他们 都拥有 相同的 Ecs
。
当您 borrow_mut()
ecs
成员 Game
然后迭代
的元素,你到达 Renderer
其中 borrow_mut()
s
相同 Ecs
。
这在运行时被检测到然后恐慌,这是预期的
RefCell
.
的行为
如果您在这两种情况下都将 borrow_mut()
更改为 borrow()
,
这不再恐慌,因为多次不可变借用
是允许的。
我不知道这段代码的确切用途,但我不确定
从 Renderer
中整体借用 Ecs
是个好主意。
我假设 interior-mutability 应该适用于每个
单独存储组件而不是整个 Ecs
.
我正在尝试使用内部可变性模式来共享可变引用。
但是,当我尝试使用与其共享的结构中的引用时,程序出现错误并出现混乱:
thread 'main' panicked at 'already borrowed: BorrowMutError'
代码如下:
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();
}
}
问题似乎在以下行:
self.ecs.borrow_mut().test();
这里有什么问题?跟性格有关系吗?还是我需要以其他方式调用函数 test
?
确实,Renderer
中的 ecs
成员是 ecs
成员的克隆
在 Game
,即他们 都拥有 相同的 Ecs
。
当您 borrow_mut()
ecs
成员 Game
然后迭代
的元素,你到达 Renderer
其中 borrow_mut()
s
相同 Ecs
。
这在运行时被检测到然后恐慌,这是预期的
RefCell
.
如果您在这两种情况下都将 borrow_mut()
更改为 borrow()
,
这不再恐慌,因为多次不可变借用
是允许的。
我不知道这段代码的确切用途,但我不确定
从 Renderer
中整体借用 Ecs
是个好主意。
我假设 interior-mutability 应该适用于每个
单独存储组件而不是整个 Ecs
.