Search code examples
ruststructoption-typebox

Initialize struct with Box<None> value


I am trying to make a flashcard program in rust, that will be saved in json format. I have made this struct for each card:

#[derive(Serialize, Deserialize)]
struct Card{
    question:String,
    answer:   String,
    status:    Status,
    strength:    f32,
    stability:    f32,
    difficulty:    f32,
    review_history: Vec<Review>,
    children:      Vec<Card>,
    parent:       Box<Option<Card>>
}

In this app a card may be related to another card in a tree-structure, so tahts why theres a parent variable and a children vector. I learned that if a struct refers to itself it has to be in a Box or something similar, and in my case, not every card has a parent, as it might be a root, so thats why i also included Option. Im not getting errors on this.

However when I try to initialize a root-card like this i get an error:

let newcard = Card{
                question: question, 
                answer: answer, 
                status: Status::Normal,
                strength: 1f32,
                stability: 1f32,
                difficulty: 0.5f32,
                review_history: review_history,
                children: children,
                parent: Box<None>,

                   };

Error i get is: "comparison operators cannot be chained" on the parent: Box<None> line. it suggests using Box::<None> but then i get the error "Constructor is not visible due to private fields".

Im not sure which fields are private, my struct, box, or the option enum?

Also Im wondering why the compiler doesnt complain about Vec<Card> not being in a box, since I just learned you use box to avoid recursive structs on the stack


Solution

  • Just use Box::new to initialize the value:

    Box::new(None)
    

    Playground

    Also Im wondering why the compiler doesnt complain about Vec not being in a box, since I just learned you use box to avoid recursive structs on the stack

    Compiler do not complain about Vec<Card> because it makes no sense to complain about it. Vec allocation are heap, only a pointer the len and capacity are stack based.

    You can check the the information in the guarantees part of the documentation:

    A vector containing the elements 'a' and 'b' with capacity 4 can be visualized as below. The top part is the Vec struct, it contains a pointer to the head of the allocation in the heap, length and capacity. The bottom part is the allocation on the heap, a contiguous memory block.

                ptr      len  capacity
           +--------+--------+--------+
           | 0x0123 |      2 |      4 |
           +--------+--------+--------+
                |
                v
    Heap   +--------+--------+--------+--------+
           |    'a' |    'b' | uninit | uninit |
           +--------+--------+--------+--------+