首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Option<Rc<RefCell<T>>>时双向引用的问题

使用Option<Rc<RefCell<T>>>时双向引用的问题
EN

Stack Overflow用户
提问于 2022-07-16 02:03:55
回答 1查看 107关注 0票数 1

我正在建立一个NES仿真器来学习锈。我很难组织部件。

我的仿真器使用结构总线与CPU和PPU通信。CPU和PPU也需要与总线通信。

我认为为总线创建一个共享指针是个好主意,这样PPU和CPU对总线具有相同的指针引用。这就是我尝试过的:游乐场。不幸的是,它没有起作用。

代码语言:javascript
复制
error[E0308]: mismatched types
  --> src/main.rs:33:9
   |
32 |     fn bus(&mut self) -> &mut Bus {
   |                          -------- expected `&mut Bus` because of return type
33 |         self.bus_helper().borrow_mut()
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |         |
   |         expected `&mut Bus`, found struct `RefMut`
   |         help: consider mutably borrowing here: `&mut self.bus_helper().borrow_mut()`
   |
   = note: expected mutable reference `&mut Bus`
                         found struct `RefMut<'_, Bus>`

如何让我的代码编译?另外,我想知道这是否是创建双向引用的最佳方式?还有别的选择吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-16 05:16:08

borrow_mut()返回一个RefMut,它是一个包装器,它维护单元格的借入计数,以便如果Rust的别名规则在运行时被违反(例如,如果一个可变引用和任何其他引用同时存在,则单元格可能会恐慌)。

您可以通过将返回类型更改为RefMut<'_, Bus>来修复此问题。

或者,为了使RefCell实现细节隐藏在调用者面前,您可以返回impl DerefMut<Target=Bus> + '_,其中写着“此方法返回一些可以作为可变Bus来删除的内容,并且捕获self的生存期”。

另外,我想知道这是否是创建双向引用的最佳方式?

通常,对于双向引用,您希望所有从“主值”(例如树根)的引用都是Rc,而另一个方向的引用则是Weak。这允许您删除主值,并自动销毁整个结构网络。如果彼此之间有两个带有Rc的值,那么当您释放对结构网络的“顶级”引用时,必须显式地中断引用周期,以避免内存泄漏。

但是,如果您发现在这种情况下您需要双向引用,在这种情况下,您有一组想相互引用的固定值,那么您可能需要一个完全不同的模式。基于操场链接,CPU和PPU对总线有很强的共享所有权,而总线对CPU和PPU的所有权较弱。(在您的模型中,应该用Weak而不是原始指针来表示。)

这意味着一个单一的实体应该拥有所有的组件,并且这个实体应该负责它们的通信。有几种方法你可以模拟这个。

  • System值拥有所有组件,该值将提供一种通信机制。这将取代Bus。可以避免循环引用,方法是在组件值需要做任何事情时,对组件值提供对System的引用。
  • 通道可以用于组件之间的通信,尽管这使得组件之间的同步消息传递更加困难。
  • 如果通道的性能影响令人望而却步,而且所需的API无法通过每次调用传递对System的引用来工作,那么如果您将System引脚到System,从而使其不能移动,则可以将引用从组件返回到System,因此不能使引用失效。这是一个高级的主题;您可能想要阅读相关文件
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73001069

复制
相关文章

相似问题

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