Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error[E0277]: the type `[u32]` cannot be indexed by `u32`

Tags:

slice

rust

vec

What am I doing wrong with the variable i below? Why does the compiler say I cannot index a Vec with a u32 and how do I fix it?

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:

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>`

Playground

like image 345
Masaki Imai Avatar asked Dec 12 '20 05:12

Masaki Imai


1 Answers

Indexing is made possible by Index and IndexMut traits.

You are using a Vec and it implements Index and IndexMut traits.

Although, it imposes a trait bound that type used to index should implement SliceIndex<[T]>:

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

SliceIndex is implemented for usize because of which it is possible to use type usize as index.

It is not implmented for u32 because of which you can't use u32 as index.

i has a type u32 because it is received from the range 0..number where number has type u32.


A simple fix would be to cast i to usize:

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

This cast can be safely done as long as you are on at least a 32 bit machine.

As per the definition of usize:

The size of this primitive is how many bytes it takes to reference any location in memory


Moreover, your code doesn't require you to use u32. Instead you should use usize from the start.

like image 153
Mihir Luthra Avatar answered Oct 20 '22 23:10

Mihir Luthra