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

为何看似违反Rust所有权语义的代码可正常编译运行?

问题复现代码

fn main() {
    let arr: [i32; 4] = [1, 2, 3, 4];
    let arr1: [i32; 4] = arr;
    println!("{:p}", &arr[0]); // 打印得到相同地址
    println!("{:p}", &arr1[0]); // 打印得到相同地址
    fn take_index(a: [i32; 4]) {
        print!("{}", a[2]);
    }
    take_index(arr1);
    print!("{}", arr[0]);
}

现象成因

这个现象完全符合Rust设计规则,不存在所有权模型失效的问题,核心原因有两点:

  • 赋值阶段根本没有触发所有权移动:固定长度、元素为基础数值类型的数组[i32;4]默认实现了Copy trait。按照Rust所有权规则,实现Copy的类型在赋值、作为函数参数传递时走值复制逻辑,不会发生所有权转移,原变量始终持有对应数据的所有权,后续访问arr完全合法,不会触发编译错误。
  • 地址相同是编译器的只读内存去重优化:两个数组首元素地址一致和多所有者没有任何关系,只是rustc做的冗余内存消除处理。当前代码里两个数组存储的内容完全一致,且全程没有对任何一个数组的修改操作,编译器会直接省略无意义的内存复制步骤,让两个不可变变量指向同一块只读内存,减少不必要的内存开销。这个优化是绝对内存安全的:只要后续代码出现任意对其中一个数组的修改操作,比如加一行arr[0] = 99;,编译器会立刻为两个变量分配独立的内存空间,再打印地址就会发现二者指向不同位置,绝不会出现多个写权限持有者操作同一块内存的情况。

内容的提问来源于stack exchange,提问作者Akash P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:24:24