1

I am wondering why list[0] and number_list[0] have the same address.

To my understanding, we passed in a reference to number_list in for_question4, so list supposed to be a reference of number_list. When we called list[0] in for_question4, it is supposed to be the same as &number_list[0].

But when I print the address, list[0] and number_list[0] are on the same address. &list[0] and &number_list[0] are on the same address.

Does function auto-dereference the vector passed in to it? Is auto-dereference a thing in Rust? If so, in what condition would it do that?

fn for_question4(list: &[&str]) {
    println!("call index without reference {:p}", list[0]); // 0x103d23d5d

    println!("call index with reference {:p}", &list[0]); // 0x7fea9c405de0
}

fn main() {
    let number_list = vec!["1", "2", "3"];
    let result = for_question4(&number_list);

    println!("call index without reference {:p}", number_list[0]); // 0x103d23d5d
    println!("call index with reference {:p}", &number_list[0]); // 0x7fea9c405de0
    println!("call index with two reference {:p}", &&number_list[0]); // 0x7ffeebf46f80
}
Finomnis
  • 18,094
  • 1
  • 20
  • 27
Jack Lien
  • 105
  • 6
  • 1
    Hey! I think you misunderstand. The `[]` operator is evaluated BEFORE the `&` operator. The `[]` operator auto-dereferences. (That's at least my understanding of how Rust works) – Finomnis May 11 '22 at 09:54
  • Oh, it does! They mentioned it in [reference](https://doc.rust-lang.org/reference/expressions/array-expr.html?highlight=index#array-and-slice-indexing-expressions) Thank you so much! – Jack Lien May 11 '22 at 10:00
  • [What are Rust's exact auto-dereferencing rules?](https://stackoverflow.com/questions/28519997/what-are-rusts-exact-auto-dereferencing-rules) – E_net4 May 11 '22 at 10:06

2 Answers2

2

The [] operator is evaluated before the & operator. The [] operator auto-dereferences.

Here are some examples:

fn main() {
    let n = vec!["1", "2", "3"];

    println!("      n[0]  {:p}", n[0]);
    println!("   (&n)[0]  {:p}", (&n)[0]);
    println!("  (&&n)[0]  {:p}", (&&n)[0]);
    println!("     &n[0]  {:p}", &n[0]);
    println!("    &(n[0]) {:p}", &(n[0]));
    println!(" &((&n)[0]) {:p}", &((&n)[0]));
    println!("&((&&n)[0]) {:p}", &((&&n)[0]));
}
      n[0]  0x5597b8ccf002
   (&n)[0]  0x5597b8ccf002
  (&&n)[0]  0x5597b8ccf002
     &n[0]  0x5597b9f3fad0
    &(n[0]) 0x5597b9f3fad0
 &((&n)[0]) 0x5597b9f3fad0
&((&&n)[0]) 0x5597b9f3fad0
Finomnis
  • 18,094
  • 1
  • 20
  • 27
1

Just figured it out thanks to @Finomnis

It was index operator ([]) that did the auto-dereference. According to reference:

For other types an index expression a[b] is equivalent to *std::ops::Index::index(&a, b), or *std::ops::IndexMut::index_mut(&mut a, b) in a mutable place expression context. Just as with methods, Rust will also insert dereference operations on a repeatedly to find an implementation.

Finomnis
  • 18,094
  • 1
  • 20
  • 27
Jack Lien
  • 105
  • 6