为什么将 `&mut &mut i32` 转换为 `*mut *mut i32` 无效

nlt*_*lta 2 unsafe reference rust

我可以像这样在 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);
}
Run Code Online (Sandbox Code Playgroud)

打印 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);
}
Run Code Online (Sandbox Code Playgroud)
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);
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

如果引用是底层的指针,我期望 &mut &mut i32 是指向 i32 的指针,但看来这个转换是错误的。

为什么允许第一次演员但不允许第二次?

Frx*_*rem 5

Rust 参考有一个所有可能的转换操作的列表。在此列表中,以下内容与该问题特别相关:

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
类型eU演员阵容由e as U
*T*V在哪里V: Sized指针到指针的强制转换
&m\xe2\x82\x81 T*m\xe2\x82\x82 T引用指针强制转换(仅当m\xe2\x82\x81ismutm\xe2\x82\x82is时const
\n
\n

从这个列表中,我们看到我们可以转换&mut T*mut T或者我们可以转换*mut T*mut V,但是没有规则让我们从 转换&mut T*mut VifT != V

\n

相反,您可以通过组合这两个规则来分两步进行转换:

\n
let xrefref: &mut &mut i32 = &mut xref;\nlet xref_ptr  = xrefref as *mut &mut i32 as *mut *mut i32;\n// &mut T -> *mut T     ^^^^^^^^^^^^^^^^\n// *mut T -> *mut V                      ^^^^^^^^^^^^^^^^\n// where T = &mut i32 and V = *mut i32\n
Run Code Online (Sandbox Code Playgroud)\n