为什么我不能用`u32`来索引`[u32]`?

问题描述 投票:0回答:3

我对下面的变量

i
做错了什么?为什么编译器说我无法用
Vec
索引
u32
以及如何修复它?

fn main() {
    let a: Vec<u32> = vec![1, 2, 3, 4];
    let number: u32 = 4;
    let mut count = 0;
    
    for i in 0..number {
        if a[i] % 2 != 0 {
            count += 1;
        } else {
            continue;
        }
    }
    println!("{}", count);
}

错误:

error[E0277]: the type `[u32]` cannot be indexed by `u32`
 --> src/main.rs:7:12
  |
7 |         if a[i] % 2 != 0 {
  |            ^^^^ slice indices are of type `usize` or ranges of `usize`
  |
  = help: the trait `SliceIndex<[u32]>` is not implemented for `u32`
  = note: required because of the requirements on the impl of `Index<u32>` for `Vec<u32>`

游乐场

rust vector slice
3个回答
18
投票

索引是通过 IndexIndexMut 特性实现的。

您正在使用

Vec
并且它实现了
Index
IndexMut
特征。

尽管如此,它强加了一个特征界限,用于索引的类型应该实现

SliceIndex<[T]>

impl<T, I> Index<I> for Vec<T>
where
    I: SliceIndex<[T]>

SliceIndex
是针对
usize
实现的,因此可以使用类型
usize
作为索引。

它没有针对

u32
实现,因此您不能使用
u32
作为索引。

i
具有类型
u32
,因为它是从范围
0..number
接收的,其中
number
具有类型
u32


一个简单的修复方法是将

i
转换为
usize
:

if a[i as usize] % 2 != 0

只要您至少在

32
位机器上,就可以安全地完成此转换。

根据 usize 的定义

这个原语的大小是引用内存中任何位置需要多少字节


此外,您的代码不需要您使用

u32
。相反,您应该从一开始就使用
usize


7
投票

快速评论:为了

number 的目的,可以使用以下结构将 
usize
 转换为 
i
,而不是永远将 
usize
 的类型更改为 
number
 或不断地将 
usize
 转换为 
for
 
仅循环:

fn main() {
    let a: Vec<u32> = vec![1, 2, 3, 4];
    let number: u32 = 4;
    let mut count = 0;

    for i in 0..number as usize {
        if a[i] % 2 != 0 {
            count += 1;
        } else {
            continue;
        }
    }
    println!("{}", count);
}

3
投票

number
的类型更改为
usize
,因此范围
for i in 0..number
也将迭代
usize
。索引通常通过
usize

完成
© www.soinside.com 2019 - 2024. All rights reserved.