问题描述
谁能解释一下为什么会编译:
Can someone explain why this compiles:
fn main() {
let a = vec![1, 2, 3];
println!("{:?}", a[4]);
}
运行时,我得到:
thread '' 在 'index out of bounds: the len is 3 but the index is 4' 处恐慌,../src/libcollections/vec.rs:1132
推荐答案
为了理解这个问题,你必须从编译器看到的角度来考虑它.
In order to understand the issue, you have to think about it in terms of what the compiler sees.
通常,编译器从不推理表达式的值,只推理其类型.因此:
Typically, a compiler never reasons about the value of an expression, only about its type. Thus:
a
属于Vec
类型4
是未知的整数类型Vec
实现了下标,所以a[4]
类型检查
a
is of typeVec<i32>
4
is of an unknown integral typeVec<i32>
implements subscripting, soa[4]
type checks
编译器对值进行推理并不是未知的,并且有多种方法可以得到它.
Having a compiler reasoning about values is not unknown, and there are various ways to get it.
- 您可以允许在编译时计算某些表达式(例如 C++
constexpr
) - 您可以将值编码为类型(C++ 非类型模板参数,使用 Peano 的数字)
- 你可以使用依赖类型来弥补类型和值之间的差距
- you can allow evaluation of some expression at compile-time (C++
constexpr
for example) - you can encode value into types (C++ non-type template parameters, using Peano's numbers)
- you can use dependent typing which bridges the gap between types and values
Rust 目前不支持其中任何一个,虽然前两个已经引起人们的兴趣,但在 1.0 之前肯定不会支持.
Rust does not support any of these at this point in time, and while there has been interest for the former two it will certainly not be done before 1.0.
因此,在运行时检查这些值,并且 Vec
的实现正确地退出(此处失败).
Thus, the values are checked at runtime, and the implementation of Vec
correctly bails out (here failing).
这篇关于为什么 Rust 编译器允许索引越界?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!