In Rust a reference is effectively a raw pointer with constraints on how it can be used, just as references are in C++.
type T = i64;
let my_variable: &T;
In C++, unlike a raw pointer, a reference cannot be nullptr
(point to address 0
) and it must be initialized when it is created. Broadly speaking, it is the same in Rust.
In Rust, a Box
type is effectively a smart pointer, analogous to C++ std::unique_ptr
.
On the subject of traits, for which there is no direct analogy in C++:
We can pass a trait object to a function using a explicit reference.
trait Trait;
fn func(arg: &dyn Trait);
However, the following does not compile:
trait Trait;
fn func(arg: dyn Trait);
This is the reason:
arg: doesn't have a size known at compile-time
It seem that dyn Trait
is not actually a fat pointer itself, but that the "reference" version &dyn Trait
is?
Box-ing the trait does compile...
fn func(arg: Box<dyn Trait>)
The question is why? I'm not totally sure this question is particularly meaningful. It seems that Box is treated by the Rust compiler in a somewhat special way, anyway.
I would have expected to see this instead:
fn func(arg: Box<&dyn Trait>)
And in fact, this seems to compile also.
So - what would the difference between these two cases be?
Box<dyn Trait>
Box<&dyn Trait>
and
dyn Trait
- (not a meaningful concept)?&dyn Trait