tl;dr: Avoid Box<T>
in general.
Actually, this rule is so important that the Rust Pointer Guide explicitly says the same. Therefore without a further ado, you should avoid Box<T>
except for these three cases:
-
When you absolutely need a trait object (
Box<Trait>
). But review carefully to see if it is indeed absolutely needed; you may try to generalize things too far, for example. -
When you have a recursive data structure. This may be mandatory when you have an inherently recursive data (e.g. scene graph), but it may also be a sign of the premature optimization. Again, review carefully to see if you need to write a separate data structure yourself, and use the
collection
crate if possible. -
When it is beneficial for the data layout. For example, this enum is 1032 bytes long in my machine:
enum A { A1(uint), A2([uint, ..128]), }
...while this enum is only 16 bytes long:
enum B { B1(uint), B2(Box<[uint, ..128]>), }
This is quite helpful for large enums. But keep it mind that this case is very unusual, so do not try to micro-optimize every enum with
Box<T>
.
Also, no matter the above exceptions say, your function should not receive or return a non-trait T
as Box<T>
. Unlike many other pointer-like types, one can freely unwrap T
out of Box<T>
and vice versa. There is no performance penalty on moving a large struct into/from the function, so let the caller decide.