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

为何Rust中此数组越界错误未在编译时被检测到?

Rust数组越界编译检查差异的原因

先看你给出的代码:

struct Foo {
    arr: [u8; 5]
}

fn main() {
    let foo = Foo{ arr: [0; 5] };
    let bar = &foo;
    println!("{}", bar.arr[100]); // 编译通过,运行时触发panic
    // println!("{}", foo.arr[100]); // 编译直接报错
}

两者的差异核心在于编译器对数组访问形式的静态分析逻辑不同:

  • 直接访问foo.arr[100]时,foo.arr是拥有所有权的固定大小数组[u8;5]。Rust编译器会在编译阶段直接对比数组长度(5)和索引值(100),发现索引超出范围后直接抛出编译错误——这是Rust针对固定大小数组的常量索引做的静态安全检查。

  • 通过引用访问bar.arr[100]时,bar.arr实际上是&[u8;5](对固定大小数组的引用)。此时Rust会自动将&[u8;5]强制转换为切片&[u8],而切片的长度在编译阶段无法被编译器精准追踪(哪怕逻辑上是固定值,编译器的静态分析规则也不会去深入推断引用背后的具体数组大小)。因此这种索引操作的越界检查只能推迟到运行时执行,所以代码能通过编译,但运行时会触发panic。

简单总结:直接操作拥有所有权的固定数组,编译器可做静态越界检查;操作数组的引用时会退化为切片操作,仅能在运行时做越界检查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:36:17