69

From the Rust guide:

To dereference (get the value being referred to rather than the reference itself) y, we use the asterisk (*)

So I did it:

fn main() {
    let x = 1;
    let ptr_y = &x;
    println!("x: {}, ptr_y: {}", x, *ptr_y);
}

This gives me the same results (x=1; y=1) even without an explicit dereference:

fn main() {
    let x = 1;
    let ptr_y = &x;
    println!("x: {}, ptr_y: {}", x, ptr_y);
}

Why? Shouldn't ptr_y print the memory address and *ptr_y print 1? Is there some kind of auto-dereference or did I miss something?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Vega
  • 2,661
  • 5
  • 24
  • 49

2 Answers2

96

Rust usually focuses on object value (i.e. the interesting part of the contents) rather than object identity (memory addresses). The implementation of Display for &T where T implements Display defers directly to the contents. Expanding that macro manually for the String implementation of Display:

impl<'a> Display for &'a String {
    fn fmt(&self, f: &mut Formatter) -> Result {
        Display::fmt(&**self, f)
    }
}

That is, it is just printing its contents directly.

If you care about object identity/the memory address, you can use the Pointer formatter, {:p}:

fn main() {
    let x = 1;
    let ptr_y = &x;
    println!("x: {}, ptr_y: {}, address: {:p}", x, ptr_y, ptr_y);
}

Output:

x: 1, ptr_y: 1, address: 0x7fff4eda6a24

playground

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
huon
  • 94,605
  • 21
  • 231
  • 225
  • 2
    I read at the Rust guide about pointers a bit after your posting and they just use "{:p}, ptr_y" because "println! will automatically dereference it for us". A short question: I usually use something like "Type name = value" or "int test = 1". It seems I can't have that in Rust as an option, "let int test = 1" gives compiler error? I know the compiler gets the type automatically but for the sake of my syntax I would like to write it in my code when declaring :(. Anyway, thanks for your answer even when I have no clue what the macro is doing exactly :). – Vega Jan 09 '15 at 02:35
  • 3
    Oh, yes,`{:p}` also works, the `p` [format specifier](http://doc.rust-lang.org/nightly/std/fmt/#formatting-traits) is [implemented for various kinds of pointers](http://doc.rust-lang.org/nightly/std/fmt/trait.Pointer.html) to just print the address. – huon Jan 09 '15 at 04:45
  • 4
    [Types are specified as `let x: Type = 1;`](http://doc.rust-lang.org/nightly/guide.html#variable-bindings). – huon Jan 09 '15 at 04:46
  • Nice, that's all I need to know :). Now I need to get a hang on the bigger stuff, I'm only used to OO and have no clue about anything that comes after this (http://doc.rust-lang.org/book/intermediate.html), especially Templates and Generic stuff. Thx for your help. – Vega Jan 09 '15 at 15:49
8
fn main() {
 let x = &42;
 let address = format!("{:p}", x); // this produces something like '0x7f06092ac6d0'
 println!("{}", address);
}
Deepak G
  • 677
  • 9
  • 10