Double reference is nothing special in Rust. In particular there’s no &&
-token-having-special-meaning weirdness going on like in C++
, instead a (prefix) &&
token has the same meaning as two seperate tokens & &
.
For any type T
, you can create the type of references to T
, that is, &'a T
. When T
itself is the type of references to yet-another-type S
, you can have &'a T
being &'a &'b S
. In case of S
being i32
, we’re back at your example. The implementation of something like &'c &'b i32
is with a pointer that points to yet another pointer whch in turn points to an i32
-value.
You can dereference z: &'c &'b i32
back to a &'b i32
by writing *z
. The underlying i32
then would be accessible under **z
. Rust does have some priciples that can operate through multiple levels of indirection. For example, you can still call &self
methods of a type S
in a double reference &&S
or even a triple reference &&&S
, etc. Something like
let x: Option<i32> = Some(0);
// how about QUINTUPLE references?!?
let y: &&&&&Option<i32> = &&&&&x;
let z: bool = y.is_some();
works just fine. Rust also allows has implicit conversions (so-called “coercion”) that can remove extra layers of references, e.g.
let x: Option<i32> = Some(0);
let y: &&&&&Option<i32> = &&&&&x;
let z: &Option<i32> = y;
There’s also certain considerations on how exactly lifetimes work with multiple levels of shared (&
) and/or mutable (&mut
) references. E.g. sharing a mutable reference via &&mut T
obviously doesn’t give you unique access to the underlying T
anymore. And in a &'c &'b i32
reference, the inner lifetime 'b
must always be longer than the outer lifetime 'c
.
By the way, something like
let z: &'c &'b i32 = &'c y;
is not actually valid Rust code. You might see this as pseudo-code somewhere when people try to explain lifetimes, but you cannot introduce (or prescribe) the lifetime of a reference in the way that the expression &'c y
seems to do.