I have a set of objects that need to know each other to cooperate. These objects are stored in a container. I'm trying to get a very simplistic idea of how to architecture my code in Rust.
Let's use an analogy. A Computer contains:
- 1
Mmu - 1
Ram - 1
Processor
In Rust:
struct Computer {
mmu: Mmu,
ram: Ram,
cpu: Cpu,
}
For anything to work, the Cpu needs to know about the Mmu it is linked to, and the Mmu needs to know the Ram it is linked to.

I do not want the Cpu to aggregate by value the Mmu. Their lifetimes differ: the Mmu can live its own life by itself. It just happens that I can plug it to the Cpu. However, there is no sense in creating a Cpu without an Mmu attached to it, since it would not be able to do its job. The same relation exists between Mmu and Ram.
Therefore:
- A
Ramcan live by itself. - An
Mmuneeds aRam. - A
Cpuneeds anMmu.
How can I model that kind of design in Rust, one with a struct whose fields know about each other.
In C++, it would be along the lines of:
>
struct Ram
{
};
struct Mmu
{
Ram& ram;
Mmu(Ram& r) : ram(r) {}
};
struct Cpu
{
Mmu& mmu;
Cpu(Mmu& m) : mmu(m) {}
};
struct Computer
{
Ram ram;
Mmu mmu;
Cpu cpu;
Computer() : ram(), mmu(ram), cpu(mmu) {}
};
Here is how I started translating that in Rust:
struct Ram;
struct Mmu<'a> {
ram: &'a Ram,
}
struct Cpu<'a> {
mmu: &'a Mmu<'a>,
}
impl Ram {
fn new() -> Ram {
Ram
}
}
impl<'a> Mmu<'a> {
fn new(ram: &'a Ram) -> Mmu<'a> {
Mmu {
ram: ram
}
}
}
impl<'a> Cpu<'a> {
fn new(mmu: &'a Mmu) -> Cpu<'a> {
Cpu {
mmu: mmu,
}
}
}
fn main() {
let ram = Ram::new();
let mmu = Mmu::new(&ram);
let cpu = Cpu::new(&mmu);
}
That is fine and all, but now I just can't find a way to create the Computer struct.
I started with:
struct Computer<'a> {
ram: Ram,
mmu: Mmu<'a>,
cpu: Cpu<'a>,
}
impl<'a> Computer<'a> {
fn new() -> Computer<'a> {
// Cannot do that, since struct fields are not accessible from the initializer
Computer {
ram: Ram::new(),
mmu: Mmu::new(&ram),
cpu: Cpu::new(&mmu),
}
// Of course cannot do that, since local variables won't live long enough
let ram = Ram::new();
let mmu = Mmu::new(&ram);
let cpu = Cpu::new(&mmu);
Computer {
ram: ram,
mmu: mmu,
cpu: cpu,
}
}
}
Okay, whatever, I won't be able to find a way to reference structure fields between them. I thought I could come up with something by creating the Ram, Mmu and Cpu on the heap; and put that inside the struct:
struct Computer<'a> {
ram: Box<Ram>,
mmu: Box<Mmu<'a>>,
cpu: Box<Cpu<'a>>,
}
impl<'a> Computer<'a> {
fn new() -> Computer<'a> {
let ram = Box::new(Ram::new());
// V-- ERROR: reference must be valid for the lifetime 'a
let mmu = Box::new(Mmu::new(&*ram));
let cpu = Box::new(Cpu::new(&*mmu));
Computer {
ram: ram,
mmu: mmu,
cpu: cpu,
}
}
}
Yeah that's right, at this point in time Rust has no way to know that I'm going to transfer ownership of let ram = Box::new(Ram::new()) to the Computer, so it will get a lifetime of 'a.
I've been trying various more or less hackish ways to get that right, but I just can't come up with a clean solution. The closest I've come is to drop the reference and use an Option, but then all my methods have to check whether the Option is Some or None, which is rather ugly.
I think I'm just on the wrong track here, trying to map what I would do in C++ in Rust, but that doesn't work. That's why I would need help finding out what is the idiomatic Rust way of creating this architecture.