0

I am writing Rust code, and I have a following situation which I usually solve by having uninitialized data in C++. The problem is: objects need references to one another. So, the objects need to be created first, and references set later. I can't figure out how to properly do this in Rust.

I am writing a Rust simulator for networks and I am trying to design an object that holds protocol stack. Let's say I need an object with first 3 layers of OSI.

Basically the types I need look like this:

struct BottomPart {
    upper_part: // reference to MiddlePart
}

struct MiddlePart {
    lower_part: ,// reference to BottomPart
    upper_part: // reference to TopPart
}

struct TopPart {
    lower_part: // reference to MiddlePart
}

struct StackedObject {
    part1: BottomPart, // or Box<BottomPart>
    part2: MiddlePart,
    part3: TopPart
}

Each part needs to be able to call methods on the part immediately above or below. For this


struct Msg{
   // some fields
}

impl BottomPart {
    fn receive(&mut self, msg: Msg) {
        //do something ....
        self.upper_part.receive(msg);
    }
}

impl MiddlePart {
    fn receive(&mut self, msg: Msg) {
        // do something based on msg
        // change state of MiddlePart
        // create another  messages
        let msg1 = Msg{}
        self.lower_part.send(msg1);
        // could also call receive on TopPart.
    }
}

impl BottomPart {
    fn send(&mut self, msg: Msg) {
        //do something ....
    }
}

StackedObject holds 3 parts. These parts might have to be Boxes because they are dynamic types (Box<dyn trait>). These parts only exist while the Object exists. They are constructed with the object, will live as long as object exists, and will be destructed with the object.

The only time the references to lower/upper parts are not valid are when the StackedObject is created. I need to create parts first, before i can set references. All other times, the references are valid.

All methods accept mutable reference to self, because state of parts is changed based on the content of the message passed.

If I was writing this code in C, I would have uninitialized pointers, which I would set in the same method in which objects are created. And I would not care about mutable and immutable functions. I can't figure out what is the best way to do this in Rust.

Rob
  • 14,107
  • 28
  • 46
  • 64
Effie
  • 716
  • 5
  • 15
  • You can use the [`Option`](https://doc.rust-lang.org/std/option/enum.Option.html) type to represent a value that may or may not be initialized. It won't help you very much though, because aliasing mutable references are disallowed. – Aiden4 Sep 28 '21 at 18:40

0 Answers0