4

What can I do to iterate over an array of integers in Rust?

fn main () {

    let mut array: Vec<i64> = vec![2];

    for k in range(3, 13195) {
        for p in array.iter() {
           if (k % p != 0) {array.push(p)};
        }        
    }
}

Gives me the compiler error:

rustc "Task2_minimalcode.rs" (im Verzeichnis: C:\Users\XXX\Documents\Rust - Project Euler)

Task2_minimalcode.rs:7:14: 7:15 error: mismatched types: expected _, found &i64 (expected integral variable, found &-ptr) [E0308] Task2_minimalcode.rs:7 if (k % p != 0) {array.push(p)};
^ Task2_minimalcode.rs:7:34: 7:35 error: mismatched types: expected i64, found &i64 (expected i64, found &-ptr) [E0308]

Task2_minimalcode.rs:7 if (k % p != 0) {array.push(p)}; ^ error: aborting due to 2 previous errors Failed compilation.

0

2 Answers 2

4

Quoth the error message:

error: mismatched types: expected i64, found &i64 (expected i64, found &-ptr)

Vec<T>::iter gives you an iterator over &T (references to T). If you don't intend to ever use the vec again, you can use for p in array or for p in array.into_iter(). If you do want to use it again, you have several options:

  • &array or array.iter(), and dereference p when using it.
  • array.iter().cloned()
  • array.iter().map(|e| *e) (effectively the same as above)

If all this talk about references doesn't make sense, you should probably read the section of the Rust Book on Pointers.

Remember that you can trick the compiler into telling you the type of a variable like so: let _:() = p; -- the error message will contain the true type.

4
  • I need that vector again. "dereference p when using it." How do I do that? &p doesn't work
    – Vega
    Commented Feb 7, 2015 at 4:14
  • 1
    &p takes a reference to p, *p dereferences a reference p. You should probably read through the Rust Book; you won't get too far without understanding references in Rust: they're everywhere.
    – DK.
    Commented Feb 7, 2015 at 4:57
  • I know what reference/derefence is, but coming from managed code (Java) I have a hard time to decide when and where to use it :(.
    – Vega
    Commented Feb 7, 2015 at 5:03
  • 1
    Which is why I recommended the book; it's not about knowing what they are in the abstract, you need to understand how they're used.
    – DK.
    Commented Feb 7, 2015 at 5:19
1

When you iterate over a slice (which is a view into the Vec), you are getting references to the items in the vector, not the items themselves.

You can fix that in two equivalent ways.

// Mark the iteration variable as a reference
for &p in &array {
    if (k % p != 0) {
        array.push(p)
    };
}

// Dereference the iteration variable
for p in &array {
    if (k % *p != 0) {
        array.push(*p)
    };
}

However, then you run into the next problem: you can't modify the Vec while you are iterating over it! If you were allowed to, the vector might need to reallocate the memory that backs it, which would then in turn invalidate all of the references in the iterator. This is a strong selling point of Rust - it prevents you from shooting yourself in the foot like this!

Without knowing what you really want to do, here's one way of doing it:

fn main() {
    let input_array = vec![2u64];
    let mut output_array = input_array.clone();

    for k in 3..13195 {
        for &p in &input_array {
            if k % p != 0 {
                output_array.push(p)
            };
        }
    }
}

See also:

3
  • My goal is Euler project task 3 (projecteuler.net/problem=3), but it seems I need to get a better algorithm. I will overthink my program, thanks for your help :).
    – Vega
    Commented Feb 7, 2015 at 5:02
  • As far as I understand, the slice will yield values of type i32, correct? I want a slice of usize values, how to specify that? Commented Aug 1, 2020 at 18:31
  • @ArtemHevorhian the slice returns values of whatever type it is. In this case, it's a Vec<u64>, so subslices and indexed values will also use u64. Change your slice's type to change subslices and indexed values.
    – Shepmaster
    Commented Aug 3, 2020 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.