A problem from THE BOOK about enum and smart pointer

I got confused when I was reading the chapter about the Box smart pointer.

enum List {
    Cons(i32, List),
    Nil,
}

This won't compile, because the size of it can't be determined.
However,

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

This compiles.

quote in THE BOOK:
"To determine how much space to allocate for a Message value, Rust goes through each of the variants to see which variant needs the most space. "

But for me, the sizes of any of the two enums can't be determined. Because we can have a String type in Message.

I also wonder that is that a enum is always stored on the heap? If so, why the size should be determined?

The might be a silly question. But please help me. Thanks in advance!

The definition for String looks something like this:

struct String {
  buffer: *mut u8,
  capacity: usize,
  length: usize,
}

In this case, even though the number of bytes behind buffer isn't known, we do know the size of a pointer and two usizes.

Values are never implicitly stored on the heap. There will always be an explicit pointer field somewhere (e.g. within the definition for String or Box).

3 Likes

I'll add a corollary to this: any Sized type that can hold information of arbitrary size uses a pointer and heap storage internally.

2 Likes

ArrayVecs are a thing. Those can use stack storage.

1 Like

Yes, but ArrayVec doesn't let you hold information of arbitrary size. It's just a wrapper around a fixed-size array which handles uninitialized memory for you.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.