You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Rust中`&mut &mut i32`强制转换为`*mut *mut i32`无效?

为什么&mut &mut i32无法直接转换为*mut *mut i32?

首先明确Rust里引用到原始指针的核心转换规则:

  • &mut T可以直接强制转换为*mut T,这是语言允许的单层级转换——&mut T本质是带生命周期、可变性约束的安全指针,转换为*mut T会丢弃这些约束,必须在unsafe上下文执行。

而你尝试的&mut &mut i32转*mut *mut i32不被允许,核心原因是:
&mut &mut i32的目标类型是&mut i32(可变引用),而非*mut i32(原始指针)。Rust不会自动递归将嵌套引用转为原始指针,必须显式处理每一层的转换逻辑。

错误原因拆解

你的代码试图一步完成两层引用到两层指针的跨层级转换,但Rust类型系统仅支持单层级的「引用→原始指针」转换。&mut &mut i32只能先转为*mut &mut i32(指向可变引用的原始指针),无法直接跳转到*mut *mut i32——内层的&mut i32不会被自动降级为原始指针。

正确实现方式

你需要分两步处理转换,或者提前将内层引用转为原始指针:

方式1:分两步转换指针

fn main() {
    let mut x = 1;
    let mut xref = &mut x;
    let mut xrefref = &mut xref;
    unsafe {
        // 第一步:将&mut &mut i32转为指向可变引用的原始指针
        let ptr_to_ref = xrefref as *mut &mut i32;
        // 第二步:解引用得到&mut i32,再转为*mut i32
        let ptr_to_ptr = *ptr_to_ref as *mut i32;
        // 直接修改目标值
        *ptr_to_ptr = 2;
    }
    println!("{}", x);
}

方式2:先将内层引用转为原始指针

如果确实需要*mut *mut i32类型,可以先把内层引用转成原始指针,再处理外层:

fn main() {
    let mut x = 1;
    // 先将&mut i32转为*mut i32
    let mut x_ptr = &mut x as *mut i32;
    let mut x_ptr_ref = &mut x_ptr;
    unsafe {
        // 此时&mut *mut i32可以直接转为*mut *mut i32
        let x_ptr_ptr = x_ptr_ref as *mut *mut i32;
        **x_ptr_ptr = 2;
    }
    println!("{}", x);
}

底层逻辑补充

虽然引用在编译后的机器码中是指针,但Rust的类型系统在编译期严格区分带安全约束的引用和无约束的原始指针。自动递归转换会绕过这些安全检查,因此Rust要求开发者显式处理每一层转换,确保在unsafe上下文中明确知晓操作风险。

内容的提问来源于stack exchange,提问作者nlta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:15:34