How do I solve this error? "the type [u32] cannot be indexed by u32"

Hello there. I'm pretty new to Rust so I'm struggling even with the most basic things.

I'm building a simple method (gen_these_many_primes) that returns a vector containing the first n primes.

For example, the call: gen_these_many_primes(4) should return the vector vec![2, 3, 5, 7]

This is my implementation:

pub fn gen_these_many_primes(n: u32) -> Vec<u32> {
    let mut primes_vec = vec![];
    let mut current_prime = 2;

    let mut current_iter: u64 = 0;
    const MAX_ITER: u64 = 10000;

    while current_prime <= n {
        if is_prime(current_prime) {
            primes_vec.push(current_prime);
            current_prime += 1;
        }

        // Avoid infinite loop
        current_iter += 1;
        if current_iter >= MAX_ITER {
            break;
        }
    }

    primes_vec
}

(Note 1: This method makes use of another is_prime method I've already implemented, which works well. You input a number and returns true if prime and false otherwise. I can post this method if necessary, I just didn't want to make the post unnecessarily long).

(Note 2: I am aware this is not an optimal algorithm, but for now I'm more interested in learning Rust than in optimization.)

So, I'm calling gen_these_many_primes from within another function called nth, which returns the nth-prime in the generated list:

pub fn nth(n: u32) -> u32 {
    let primes = gen_these_many_primes(n);
    return primes[n];
}

For example, the call nth(3) should return 7. nth(0) should return 2.

However, when I call this method, I obtain the following error:

error[E0277]: the type [u32] cannot be indexed by u32

I've run the command rustc --explain E0277 as suggested, and it mentions something about traits, but I don't understand the error very well.

Maybe someone can point me in the right direction.

Forever grateful.

Jose.

Arrays need to be indexed by a usize type. Nowhere in the code you pasted do I see you doing any array indexing, so that code should compile, but perhaps in you nth function, you are indexing into the returned array...

a usize is basically a number like a u64 on most platforms (although may be smaller on some embedded platforms, and may be larger in the future). You are allowed to typecast using the "as" operator. However, it's almost always the case that you are better off thinking as indexing variables separate and un-mixable with ordinary numbers, unless you have a very good reason for mixing them.

On another note, I think there may be a logic bug in your gen_these_many_primes function. I know that's not the purpose of your post, and I may be misreading it, but consider what happens after 3 is added to the array.

current_prime is then incremented to 4, and the loop spins until the line
if current_iter >= MAX_ITER { causes the loop to break, regardless of what value for n was given as the function argument.

1 Like

There is a lengthy discussion of indexing arrays with integers and the use of "as" and other methods here: "as" considered harmful?

I know what you mean but it turns out that in a awful lot of code we want to us integers as array indices.

Consider a function like:

fn some_func(n: u32) -> u32 {
    ...
    calculate something
    ...
    something
}

One might want to replace that with a look up table:

    let result = table[n];

The point being that the thing we want to use as an index is often a real quantity with meaning other than just being an array index.

Somehow the notion of "array index" which is an integer, gets mixed up with "memory pointer" which is a usize in Rust.

1 Like

Thank you a lot guys, but... how do I go about solving my problem? Should I just stick to arrays instead of vectors?
Here's the is_prime method, just in case you want to try everything out on your own:

pub fn is_prime(n: u32) -> bool {
    for i in 1..n {
        if i > 2 && i < n && n % i == 0 || i < 2  {
            return false;
        }
    }
    return true;
}

(Not optimized, but I'm focusing on Rust not on optimization at this point).

Having all three methods, you can try calling

println!("{}", nth(3));

inside of main, and will get the error I stated in the title.

By the way, how do you format the code, add colors, etc. so that it's more readable in the forum?

I didn't read this. I will take a look at it, however as you said that's not the point of the post.
Thank you for pointing it out. Let me give it a thought.

pub fn gen_these_many_primes(n: usize) -> Vec<u32> {
    let mut primes_vec = vec![];
    let mut current_prime = 2;

    const MAX_ITER: u32 = 10000;

    while primes_vec.len() <= n {
        if is_prime(current_prime) {
            primes_vec.push(current_prime);
        }
        current_prime += 1;

        // Avoid infinite loop
        if current_prime >= MAX_ITER {
            break;
        }
    }

    primes_vec
}

pub fn nth(n: usize) -> u32 {
    let primes = gen_these_many_primes(n);
    return primes[n];
}

pub fn is_prime(n: u32) -> bool {
    for i in 2..n {
        if n % i == 0 {
            return false;
        }
    }
    return true;
}

Fixed all the issues that I spotted. As you say there are many opportunities to improve performance by orders of magnitude.

2 Likes

Use 3 "backtick" marks to open and close your code block.

```

pub fn is_prime(n: u32) -> bool {

```

pub fn is_prime(n: u32) -> bool {
1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.