我对下面的问题感到很困惑。如果我理解正确的话
let x = &42;
被内部膨胀到
let x_value = 42;
let x = &x;
我想我在《铁 rust 》一书中见过这一点,但我找不到它的参考文献。
我的问题与以下代码有关:
let x = 42;
let rx = &x;
let px = rx as *const i32 as *mut i32;
unsafe {
*px = 0;
}
println!("{}", x);
正如预期的那样,这将打印0
。但是,如果我写
let rx = &42;
let px = rx as *const i32 as *mut i32;
unsafe {
println!("Deref");
*px = 0;
}
println!("{}", x);
程序在打印出Deref
后终止。很明显,当px
被取消引用时出错了。我想我关于let x = &42
在内部扩展的第一个评估是错误的。
2条答案
按热度按时间2j4z5cfb1#
您正在调用未定义的行为。来自Rust Reference:
12.3行为被视为未定义
以下是所有Rust代码中禁止的行为列表,包括不安全块和不安全函数。[...]
let
绑定拥有的数据),除非该数据包含在UnsafeCell<U>
中。因为你正在改变不可变的数据,你正在调用未定义的行为。事实上,它在第一个版本中工作只是(坏)运气。
bkhjykvo2#
这里你在stack上创建一个新的变量,并在那里写入来自程序代码的值42,所以当创建一个引用时,它引用的是stack上的这个值。您可以访问堆栈上的值并能够更改它。
在第二种情况下
你创建了一个直接指向存储代码(指令和其他数据)的内存部分中的值的引用。2而这部分内存是不可变的。