指针在Rust中解除引用

jan*_*jan 3 rust

我对以下问题感到困惑.如果我理解正确的话

let x = &42;
Run Code Online (Sandbox Code Playgroud)

在内部扩展到

let x_value = 42;
let x = &x;
Run Code Online (Sandbox Code Playgroud)

我想我已经在Rust书中看到了这个,但我找不到它的引用.

我的问题是关于以下代码:

let x = 42;
let rx = &x;
let px = rx as *const i32 as *mut i32;
unsafe {
  *px = 0;
}
println!("{}", x);
Run Code Online (Sandbox Code Playgroud)

正如预期的那样打印0.但是,如果我写的话

let rx = &42;
let px = rx as *const i32 as *mut i32;
unsafe {
  println!("Deref");
  *px = 0;
}
println!("{}", x);
Run Code Online (Sandbox Code Playgroud)

程序在打印完毕后终止Deref.当px被取消引用时,显然会出现问题.我想我对let x = &42内部扩展的第一次评估是错误的.

Cor*_*lks 7

您正在调用未定义的行为.来自Rust参考:

12.3行为被认为是未定义的

以下是所有Rust代码中禁止的行为列表,包括不安全块和不安全函数.[...]

  • 变异非可变数据(即通过共享引用或let绑定所拥有的数据到达的数据),除非该数据包含在UnsafeCell<U>.

由于您正在改变非可变数据,因此您正在调用未定义的行为.它在第一个版本中完全有效的事实只是(坏)运气.