我有一个 2D 向量,它拒绝使用i32值进行索引,但如果我使用as usize以下方法转换这些值,则可以工作:
#[derive(Clone)]
struct Color;
struct Pixel {
color: Color,
}
fn shooting_star(p: &mut Vec<Vec<Pixel>>, x: i32, y: i32, w: i32, h: i32, c: Color) {
for i in x..=w {
for j in y..=h {
p[i][j].color = c.clone();
}
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
当我编译时,我收到错误消息
#[derive(Clone)]
struct Color;
struct Pixel {
color: Color,
}
fn shooting_star(p: &mut Vec<Vec<Pixel>>, x: i32, y: i32, w: i32, h: i32, c: Color) {
for i in x..=w {
for j in y..=h {
p[i][j].color = c.clone();
}
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
如果我将代码更改为
p[i as usize][j as usize].color = c.clone();
Run Code Online (Sandbox Code Playgroud)
然后一切正常。然而,这感觉就像是一个非常奇怪的选择,没有理由不被Vec类型处理。
在文档中,有很多示例,例如
assert_eq!(vec[0], 1);
Run Code Online (Sandbox Code Playgroud)
根据我的理解,如果默认情况下没有小数的普通数字是 an i32,那么没有理由使用i32to 索引不起作用。
与 Java、C# 甚至 C++ 不同,Rust 中的数字文字没有固定类型。文字的数字类型通常由编译器推断,或使用后缀(0usize、0.0f64等)显式声明。在这方面,0文字 in的类型assert_eq!(vec[0], 1);被推断为 a usize,因为 Rust 只允许Vec按类型的数字进行索引usize。
至于使用usize作为索引类型背后的基本原理:ausize相当于目标架构中的一个词。因此, ausize可以指代运行程序的计算机的所有可能内存位置的索引/地址。因此,向量的最大可能长度是 a isize( isize::MAX == usize::MAX / 2) 中可以包含的最大可能值。usize对 a使用大小和索引Vec可防止创建和使用大于可用内存本身的向量。
此外,使用足够大的无符号整数来引用所有可能的内存位置允许删除两个动态检查,一个,提供的大小/索引是非负的(如果isize使用,则必须手动执行此检查) ,第二,创建向量或解引用向量的值不会导致计算机内存不足。然而,只有当向量中存储的类型适合一个词时,才保证后者。