我可以像这样在rust中将&mut i32转换为*mut i32
fn main() {
let mut x = 1;
let mut xref = &mut x;
unsafe {
let xref_ptr = xref as *mut i32;
*xref_ptr = 2;
}
println!("{}", x);
}
打印2。
但是我不能将&mut &mut i32转换为*mut *mut i32,我不明白为什么。
fn main() {
let mut x = 1;
let mut xref = &mut x;
let mut xrefref = &mut xref;
unsafe {
let xrefptr = xrefref as *mut (*mut i32);
**xrefptr = 2;
}
println!("{}", x);
}
error[E0606]: casting `&mut &mut i32` as `*mut *mut i32` is invalid
--> src/main.rs:16:23
|
16 | let xrefptr = xrefref as *mut (*mut i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
如果引用是指针,我期望&mut &mut i32是指向指向i32的指针的指针,但似乎这种强制转换是错误的。
为什么允许第一次强制转换而不允许第二次强制转换?
Rust引用包含所有可能的强制转换操作的列表。在这个列表中,以下是与这个问题特别相关的:
e |
U |
e as U |
|
---|---|---|---|
*T |
*V whereV: Sized |
指针到指针的转换 | |
&m₁ T |
*m₂ T |
对指针强制转换的引用(仅当m₁ 为mut 或m₂ 为const 时) |
正如@PitaJ指出的那样,通常一次只允许进行一次强制转换,并且强制转换不具有传递性。也就是说,T as U
有效,U as V
有效并不意味着T as V
有效。
但是您可以分两步(用安全的代码!)进行强制转换:
let mut x = 1;
let mut xref = &mut x;
let mut xrefref = &mut xref;
let xrefptr = (xrefref as *mut &mut i32) as *mut *mut i32;
unsafe {
**xrefptr = 2;
}
println!("{}", x); // 2