gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 11:30:46 25 4
gpt4 key购买 nike

我正在尝试使用内部可变性模式来共享可变引用。
但是,当我尝试使用与其共享的结构中的引用时,程序会因错误而 panic :

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

最佳答案

实际上,ecs中的Renderer成员是ecs成员的克隆
Game中,即它们都拥有相同的Ecs
当您对borrow_mut()中的ecs成员进行Game时,然后对其进行迭代
元素,您会到达Renderer,其中borrow_mut()
相同的Ecs
这是在运行时检测到的,然后出现了紧急情况,RefCell的行为。
如果您在两种情况下都只是将borrow_mut()更改为borrow()
这不再 panic 了,因为有多个不可变的借用
被允许。
我不知道这段代码的确切用途,但我不确定
Ecs整体上借鉴Renderer是一个好主意。
我认为内部可变性应适用于每个
单独存储组件,而不是整个Ecs

关于rust - “BorrowMutError”使用内部可变性模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63864208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com