1

I'm trying to learn Rust. While playing around with references, I noticed that Rust apparently automatically dereferences primitive types.

fn takes_ref(bytes: &[u8; 2]) {
    println!("str[0]: {}", bytes[0]); // <-- bytes[0] compiles even though it's a ref.
}
fn takes_ref_correct(bytes: &[u8; 2]) {
    println!("str[0]: {}", (*bytes)[0]); // This is correct, first I dereference bytes and then access it's contents
}
fn takes_ref_to_ref(bytes: &&[u8; 2]) { // takes reference to reference
    println!("str[0]: {}", bytes[0]); // this works as well
}

All these functions compile and behave in the exact same way. Why? Does the [] operator automatically dereferences refs? Do any other operators behave like this?

nwroot
  • 11
  • 1
  • All methods that are implemented for a type automatically reduce multiple levels of references to just one reference (because that's what you typically need and it removes this ugly (*bytes)[0] syntax most of the times – Alexey S. Larionov Feb 05 '21 at 21:48
  • [As the reference explains](https://doc.rust-lang.org/stable/std/ops/trait.Index.html), `bytes[0]` is really just syntactic sugar for `*bytes.index(0)`. With that in mind, the duplicate explains the general rules for auto-dereferencing. (TL;DR: yes) – Frxstrem Feb 05 '21 at 21:55
  • Array primitives do not implement index() though. (replacing bytes[0] with *bytes.index(0) fails with a compilation error about index not being implemented for [u8; 2]) – nwroot Feb 05 '21 at 22:03
  • 2
    All `std::ops` traits must be imported before you can use the method syntax. Add `use std::ops::Index;` first and it should work. (However, you're actually right that arrays do not implement `Index` -- there is first an unsized coercion from `[u8; 2]` to `[u8]`, which is also mentioned at the linked question.) – trent Feb 05 '21 at 22:10
  • 3
    Rust, by the way, doesn't really have a concept of "primitive types" -- there are built-in types and library types, but built-in types include arbitrarily complex arrays, tuples, `str`, and references, so the term "primitive" doesn't really describe a meaningful distinction. Rust users don't often find it useful to talk about a type's "primitiveness". – trent Feb 05 '21 at 22:16

0 Answers0