5

I saw some code which looks like this:

fn test <'a> (&'a mut &'a str) {}

I know that 'a is a lifetime and that the & is a reference.

However I have trouble understanding a double reference &&.

In my understanding a reference is a pointer, so is a && a pointer to another pointer or something else?

Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155
  • a reference is a reference, if a reference would be a pointer we would have name it pointer not reference. so && is a reference of a reference. – Stargateur Feb 28 '21 at 11:14
  • But a reference is a type of pointer right? – Willem van der Veen Feb 28 '21 at 11:15
  • Yeah, but so are lots of other things in Rust, like `Box`, `Vec` and of course *raw pointers* like `*mut T`. Most pointers you use are more than just pointers. – trent Feb 28 '21 at 12:25
  • 1
    To future readers, this question is about the *type* `&&T`, not to be confused with invoking the [borrow operator](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators) twice (i.e. `&&var`) or with the [boolean operator](https://doc.rust-lang.org/reference/expressions/operator-expr.html#lazy-boolean-operators) (i.e. `a && b`) – kmdreko Feb 28 '21 at 21:39

1 Answers1

6

In my understanding a reference is a pointer

Yes, a reference is just a pointer with special borrow-checking semantics. Pointers, and thus references, are just addresses in memory (and sometimes a size as well but that's irrelevant for this answer), which means that they essentially have a value of their own, separate from the value that they "point to" or "reference." That's why code like this can work:

fn main() {
    let num1 = 1;
    let num2 = 2;
    let mut num_ref = &num1;
    dbg!(num1, num2, num_ref); // num1 and num2 are 1 and 2 and num_ref is &1
    num_ref = &num2;
    dbg!(num1, num2, num_ref); // num1 and num2 are 1 and 2 and num_ref is &2
}

The values under the reference don't change, but the reference itself changes.

So, &mut &T is a mutable reference to an immutable reference, which means you can change the reference underneath the mutable reference:

fn make_reference_one(r: &mut &i32) {
    *r = &1;
}

fn main() {
    let mut num_ref = &2;
    dbg!(num_ref); // is &2
    make_reference_one(&mut num_ref);
    dbg!(num_ref); // is now &1
}
Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • I think it should be `The values under the reference change, but the reference itself does not change.`. Just like the address pointer resides does not changes but the value pointed by the pointer changes. @Willem @Aplet – yokus Feb 11 '23 at 21:27