【问题标题】:Do I have to use a usize to access elements of a vector?我必须使用 usize 来访问向量的元素吗?
【发布时间】:2018-05-30 04:24:01
【问题描述】:

我有一个 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() {}

当我编译时,我收到错误消息

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 来索引没有理由不应该工作。

【问题讨论】:

    标签: rust


    【解决方案1】:

    与 Java、C# 甚至 C++ 不同,Rust 中的数字文字没有固定类型。文字的数字类型通常由编译器推断,或使用后缀(0usize0.0f64 等)明确说明。在这方面,assert_eq!(vec[0], 1); 中的0 文字的类型推断usize,因为Rust 允许Vec 仅按usize 类型的数字进行索引。 p>

    至于使用usize 作为索引类型背后的基本原理:usize 相当于目标架构中的一个单词。因此,usize 可以引用运行程序的计算机的所有可能内存位置的索引/地址。因此,向量的最大可能长度是isize (isize::MAX == usize::MAX / 2) 中可以包含的最大可能值。为 Vec 使用 usize 大小和索引可防止创建和使用大于可用内存本身的向量。

    此外,使用刚好足够大以引用所有可能的内存位置的无符号整数允许删除两个动态检查,一个,提供的大小/索引是非负数(如果使用isize,此检查将必须手动实现),第二,创建向量或取消引用向量的值不会导致计算机内存不足。但是,只有当向量中存储的类型适合一个词时,才能保证后者。

    【讨论】:

    • 这是有道理的,虽然它有点痛苦。它真的必须隐含地产生多大的性能影响?如果某些东西对速度至关重要,那么他们不应该使用不同的数据结构吗?
    • “与 Java、C# 甚至 C++ 不同,Rust 中的数字文字没有固定类型。” ??? "因此,向量的最大可能长度是一个usize 中可以包含的最大可能值。" => "The theoretical upper bound on object and array size is the maximum isize value.
    • 如果你想问为什么SliceIndex(允许将类型用于索引的特性)的实现不适用于其他数字类型,this answer 说得很好。跨度>
    • @Stargateur:C++:auto x = 0; // x: int Rust:let x = 0; // x: {integer} (to be inferred later)。感谢您提供最大对象/数组大小提示!我已经编辑了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2012-02-01
    • 2018-01-26
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    相关资源
    最近更新 更多