Rust中指向自身的引用如何工作?内存布局解析
为什么Rust中
y = &y后引用仍指向初始值? 核心原因:Rust的自动解引用强制转换(Deref Coercion)
你遇到的现象本质是Rust类型系统的隐式转换在起作用,y = &y并没有让y存储自身的地址,而是自动完成了解引用,保留了原有的引用目标。
分步解析代码执行过程
1. 初始状态(let mut y = &x;之后)
内存布局和你理解的一致:
| 变量名 | 地址 | 值(存储的地址) |
|---|---|---|
| x | a1 | 1(i32类型) |
| y | a2 | a1(&i32类型) |
此时y的类型是&i32,指向x。
2. y = &y的实际执行逻辑
- 右边的
&y是&&i32类型(对&i32的引用,也就是指向指针的指针)。 - 左边的
y是&i32类型,Rust会自动触发解引用强制转换:将&&i32隐式解引用一次,得到内层的&i32(也就是y原来存储的a1)。 - 换句话说,
y = &y等价于y = *&y,而*&y就是y本身的值(a1)。
因此,执行这行代码后,y存储的地址完全没有变化,还是a1。
3. 执行后的内存布局
和初始状态完全相同:
| 变量名 | 地址 | 值(存储的地址) |
|---|---|---|
| x | a1 | 1(i32类型) |
| y | a2 | a1(&i32类型) |
这也是两次println!输出完全一致的原因——y的指向从未改变。
如何让引用真正指向自身?
如果想要实现“引用指向自身”的效果,需要绕开Rust的自动解引用机制,比如使用裸指针(不安全操作):
let x = 1; // 声明y为裸指针类型 let mut y: *const i32 = &x; println!("{:p} -> {}", y, unsafe { *y }); // 输出x的地址和1 // 强制将y的地址转换为*i32类型的裸指针 y = &y as *const _ as *const i32; println!("{:p}", y); // 输出y自身的地址 // 注意:此处解引用是未定义行为,因为y存储的是指针地址,不是i32值 // unsafe { println!("{}", *y); }
但裸指针操作属于Rust的不安全范畴,可能导致内存错误,实际开发中需谨慎使用。
内容的提问来源于stack exchange,提问作者magva
相关产品推荐
相关产品推荐

