Подтвердить что ты не робот

Почему печать указателя печатает то же самое, что и печать разыменованного указателя?

Из руководства Rust:

Чтобы разыменовать (получить значение, а не ссылку) y, мы используем звездочку (*)

Итак, я сделал это:

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

Это дает мне те же результаты (x = 1; y = 1) даже без явного разыменования:

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

Почему? Не следует ли ptr_y распечатать адрес памяти и *ptr_y распечатать 1? Есть ли какая-то автоматическая развязка или я что-то пропустил?

4b9b3361

Ответ 1

Rust обычно фокусируется на значении объекта (то есть интересной части содержимого), а не на идентичности объекта (адреса памяти). Реализация Display для &T где T реализует Display напрямую относится к содержимому. Расширение этого макроса вручную для реализации String в Display:

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

То есть он просто печатает свое содержимое напрямую.

Если вы заботитесь об идентичности объекта/адресе памяти, вы можете использовать форматировщик Pointer, {:p}:

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

Выход:

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

детская площадка

Ответ 2

fn main() {
 let x = &42;
 let address = format!("{:p}", x); // this produces something like '0x7f06092ac6d0'
 println!("{}", address);
}