我有一个二维向量拒绝使用 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() {}
编译时出现错误信息
error[E0277]: the trait bound `i32: std::slice::SliceIndex<[std::vec::Vec<Pixel>]>` is not satisfied
--> src/main.rs:11:13
|
11 | p[i][j].color = c.clone();
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[std::vec::Vec<Pixel>]>` is not implemented for `i32`
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `std::vec::Vec<std::vec::Vec<Pixel>>`
如果我把代码改成有
p[i as usize][j as usize].color = c.clone();
然后一切正常。然而,这感觉就像是一个非常奇怪的选择,没有理由不由 Vec
处理。类型。
在documentation , 有很多这样的例子
assert_eq!(vec[0], 1);
据我了解,如果没有小数点的普通数字默认为 i32
, 那么就没有理由使用 i32
索引不应该工作。
最佳答案
与 Java、C# 甚至 C++ 不同,Rust 中的数字文字没有固定类型。文字的数字类型通常由编译器推断,或使用后缀(0usize
、0.0f64
等)明确说明。在这方面,assert_eq!(vec[0], 1);
中 0
文字的类型被推断为 usize
,因为 Rust 仅允许 Vec
按 usize
类型的数字进行索引。
至于使用 usize
作为索引类型背后的基本原理:usize
等同于目标体系结构中的 word。因此,usize
可以引用运行程序的计算机的所有可能内存位置的索引/地址。因此,向量的最大可能长度是 isize
中可以包含的最大可能值 (isize::MAX == usize::MAX/2
)。对 Vec
使用 usize
大小和索引可防止创建和使用大于可用内存本身的矢量。
此外,使用刚好足以引用所有可能的内存位置的无符号整数允许删除两个动态检查,一个,提供的大小/索引是非负的(如果 isize
是使用时,必须手动执行此检查),第二,创建向量或取消引用向量的值不会导致计算机内存不足。然而,只有当存储在向量中的类型适合一个词时,后者才能得到保证。
关于rust - 我是否必须使用 usize 来访问向量的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50596364/