In Rust, how can a reference be a pointer to a pointer-to-a-pointer? -


today's rust mystery section 4.9 of rust programming language, first edition. example of references , borrowing has example:

fn main() {     fn sum_vec(v: &vec<i32>) -> i32 {         return v.iter().fold(0, |a, &b| + b);     }      fn foo(v1: &vec<i32>) -> i32 {         sum_vec(v1);     }      let v1 = vec![1, 2, 3];      let answer = foo(&v1);     println!("{}", answer); } 

that seems reasonable. prints "6", you'd expect if v of sum_vec c++ reference; it's name memory location, vector v1 defined in main().

then replaced body of sum_vec this:

fn sum_vec(v: &vec<i32>) -> i32 {     return (*v).iter().fold(0, |a, &b| + b); } 

it compiled , worked expected. okay, that's not… entirely crazy. compiler trying make life easier, that. confusing, have memorize specific tic of language, not entirely crazy. tried:

fn sum_vec(v: &vec<i32>) -> i32 {     return (**v).iter().fold(0, |a, &b| + b); } 

it still worked! hell?

fn sum_vec(v: &vec<i32>) -> i32 {     return (***v).iter().fold(0, |a, &b| + b); } 

type [i32] cannot dereferenced. oh, thank god, makes sense. have expected 2 iterations earlier!

references in rust aren't c++ "names place in memory," are they? they're not pointers either, , rules them seem either esoteric or highly ad-hoc. happening such reference, pointer, , pointer-to-a-pointer work equally here?

the rules not ad-hoc nor esoteric. inspect type of v , it's various dereferences:

fn sum_vec(v: &vec<i32>) {     let () = v; } 

you'll get:

  1. v -> &std::vec::vec<i32>
  2. *v -> std::vec::vec<i32>
  3. **v -> [i32]

the first dereference understand. second dereference deref trait. vec<t> dereferences [t].

when performing method lookup, there's straight-forward set of rules:

  1. if type has method, use , exit lookup.
  2. if reference type has method, use , exit lookup.
  3. if type can dereferenced, so, return step 1.
  4. else lookup fails.

references in rust aren't c++ "names place in memory,"

they absolutely names place in memory. in fact, compile down same c / c++ pointer know.


Comments