Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How solve "cannot index a value of type `usize`" error?

Tags:

rust

I am trying to measure the speed of Vec's [] indexing vs. .get(index) using the following code:

extern crate time;

fn main() {
    let v = vec![1; 1_000_000];
    let before_rec1 = time::precise_time_ns();

    for (i, v) in (0..v.len()).enumerate() {
        v[i]
    }
    let after_rec1 = time::precise_time_ns();
    println!("Total time: {}", after_rec1 - before_rec1);


    let before_rec2 = time::precise_time_ns();

    for (i, v) in (0..v.len()).enumerate() {
        v.get(i)
    }
    let after_rec2 = time::precise_time_ns();
    println!("Total time: {}", after_rec2 - before_rec2);
}

but this returns the following errors:

error: cannot index a value of type `usize`
 --> src/main.rs:8:9
  |
8 |         v[i]
  |         ^^^^

error: no method named `get` found for type `usize` in the current scope
  --> src/main.rs:17:11
   |
17 |         v.get(i)
   |           ^^^

I'm confused why this doesn't work, since enumerate should give me an index which, by its very name, I should be able to use to index the vector.

  1. Why is this error being thrown?
  2. I know I can/should use iteration rather than C-style way of indexing, but for learning's sake what do I use to iterate over the index values like I'm trying to do here?
like image 992
almel Avatar asked Sep 12 '25 06:09

almel


1 Answers

You, pal, are mightily confused here.

fn main() {
    let v = vec![1; 1_000_000];

This v has type Vec<i32>.

for (i, v) in (0..v.len()).enumerate() {
    v[i]
}

You are iterating over a range of indexes, from 0 to v.len(), and using enumerate to generate indices as you go:

  • This v has type usize
  • In the loop, v == i, always

So... indeed, the compiler is correct, you cannot use [] on usize.


The program "fixed":

extern crate time;

fn main() {
    let v = vec![1; 1_000_000];

    let before_rec1 = time::precise_time_ns();

    for i in 0..v.len() {
        v[i]
    }

    let after_rec1 = time::precise_time_ns();
    println!("Total time: {}", after_rec1 - before_rec1);


    let before_rec2 = time::precise_time_ns();

    for i in 0..v.len() {
        v.get(i)
    }

    let after_rec2 = time::precise_time_ns();
    println!("Total time: {}", after_rec2 - before_rec2);
}

I would add a disclaimer, though, that if I were a compiler, this useless loop would be optimized into a noop. If, after compiling with --release, your programs reports 0, this is what happened.

Rust has built-in benchmarking support, I advise that you use it rather than going the naive way. And... you will also need to inspect the assembly emitted, which is the only way to make sure that you are measuring what you think you are (optimizing compilers are tricky like that).

like image 144
Matthieu M. Avatar answered Sep 14 '25 21:09

Matthieu M.