rust - 就我的 PDP 模拟器的数据结构建模寻求建议
问题描述
(请不要作为一个主观问题来结束 - 我在“发现铁锈成语”的轨道上征求其他旅行者的建议)
我正在将我的 PDP11 模拟器从 c++ 移植到 rust。我正在尝试获得正确的数据结构。
从逻辑上讲,PDP11 系统由 CPU、总线(拥有所有 IO 设备)和一些 RAM 组成。每个组件都需要相互通信。所以我从这个开始
pub struct System {
ram: Memory,
cpu: Cpu,
bus: Bus,
}
让我们看一个功能
impl Cpu{
pub fn step(&self) -> (){
let inst = ram.get_word(self.pc);
// decode inst
// execute it
}
}
一小步。模拟器的核心。它需要访问 ram(和总线,但此处未显示)。当然,这是不完整的,也没有办法到达 ram
我的第一个努力是如何连接这些“子”结构以使指针返回到这个系统对象。不行,他们需要在两个方向都保持沉默,混乱随之而来。
然后我想,既然每个东西只有一个,我只是把整个东西扁平化成一个对象,所有的方法和数据都存在于系统对象上。但这并不干净,这些是逻辑上不同的子系统,我真的想将它们建模为单独的实体。
然后我有一个启示。生锈要我做什么?传入函数调用它需要的数据。像这样
impl System{
pub fn step(&mut self){
self.cpu.step(&mut self)
}
}
和
impl Cpu{
pub fn step(&self, &mut sys:System) -> (){
let inst = sys.ram.get_word(self.pc);
// decode inst
// execute it
}
}
(有一个 UI 通过 FFI 调用堆栈更高的这些系统方法)。现在我知道这不起作用并且已经阅读了它为什么起作用。
我已经被困了一个星期,试图找出安排这些结构的最佳方式。请问有什么建议吗?
解决方案
我的第一个努力是如何连接这些“子”结构以使指针返回到这个系统对象
这在 C++(或任何语言,真的)中也是一个坏主意。循环不好!
传入函数调用它需要的数据。
是的,这是一个可以在许多项目中看到的解决方案,但要考虑到您也在创建一个循环。在这种情况下,循环是暂时的而不是永久的,但它仍然是一个循环。
相反,您可以做的是只传递第一个子系统需要的子系统。这消除了循环。甚至只是您可能需要的子系统的一部分。
然后我想,既然每个东西只有一个,我只是把整个东西扁平化成一个对象,所有的方法和数据都存在于系统对象上。但这并不干净,这些是逻辑上不同的子系统,我真的想将它们建模为单独的实体。
也许吧,但要考虑到,在许多情况下,现实生活中的实体并不是系统建模时的最佳划分点。
当您的子系统依赖于许多其他子系统甚至整个系统时,可能会创建循环,那么这可能是您选择的分区不是最好的一个症状。
如果您想让子系统保持原样分离并且避免循环被证明是不可能的,您可以诉诸解决方案,例如RefCell
或复制语义。
推荐阅读
- c# - 使用 ITfoxtec.Identity.Saml2 映射 SAML 声明
- c# - Xamarin Forms Android 应用程序上的 RestSharp 请求停止
- qt - 对象构造函数
- mysql - hibernate hbm2ddl.auto 创建奇怪的 SQL 查询
- php - 类不符合 psr-4 自动加载标准。跳过
- reactjs - 键入“可变引用对象”
' 不可分配给类型 'string | (((实例:HTMLInputElement | null)=> void) - javascript - 使用打字稿中的通用类型从具有正确类型的对象返回属性
- reactjs - 使用反应钩子提交后清除输入
- c# - Blazor Server:无法在 Linux 上使用 nginx 进行部署?
- swiftui - 如何在 SwiftUI 中将模糊效果作为背景?