3

This aspect of Rust seems rather bizarre at first, and I'd like to know how for typing works in this case.

fn sum1(v: &mut Vec<i32>) -> i32 {
    // I know I don't mutate v, but that's not the point
    let mut s = 0;
    for e in v {
        s += *e;
        // s += e; <- Err!
    }
    s
}

fn sum2(v: &Vec<i32>) -> i32 {
    let mut s = 0;
    for e in v {
        s += e; // Okay?
    }
    s
}

fn main() {
    let mut v = vec![1, 2, 3];
    println!("{}", sum1(&mut v));
    println!("{}", sum2(&v));
}

At first I was confused as to why it wanted me to dereference in sum1. But okay, it's saying AddAssign<&mut i32> is not implemented, so I see that e is &mut i32. That's really awesome for changing e on the fly.

But now, with that information, why does sum2 compile? It seems like AddAssign<&i32> is indeed implemented (Which I tested separately), so it's possible that it's using that AddAssign method on a &i32, but then again it's also possible that e is simply i32. My question boils down to:

Is e an i32, or an &i32?

I don't know enough about references to easily check the difference myself (By using something other than i32 and checking for crashes). &i32 is the most logical but I would like to know for sure.

Coming from C, mixing between pointers and values is extremely confusing, and it has already taken me quite a bit to get used to with functions automatically dereferencing/referencing their arguments (which I don't think I've really done yet).

EDIT:

The type could be verified (And answer my question) with How do I print the type of a variable in Rust?, which is useful to mess around with but doesn't directly answer how for loops work. What is the exact definition of the for loop in Rust? helps a lot, and What is the difference between iter and into_iter? talks about a related IntoIterator trait that can cause for loop confusion.

Nicholas Pipitone
  • 4,002
  • 4
  • 24
  • 39
  • [This here](https://stackoverflow.com/questions/23920968/why-does-the-binary-operator-not-work-with-two-mut-int) looks related, but the answer says just *"the `+` operator is not implemented for `&mut i32`"*. From that answer, it's not clear *why* it's not implemented. – Andrey Tyukin Nov 01 '18 at 22:48
  • I can see that `+` is implemented for `&` and not `&mut`, but my question is more about what the type of `e` is in `sum2`. It doesn't appear that Rust has a `typeof` operator to check against. – Nicholas Pipitone Nov 01 '18 at 22:55
  • 1
    *My question boils down to: "Is e an i32, or an &i32?"* — Does [How do I print the type of a variable in Rust?](https://stackoverflow.com/q/21747136/155423) answer your question? – Shepmaster Nov 01 '18 at 22:59
  • Hm, it may but moreso I was looking for something with respect to how for loops over vectors and iterators work. My `typeof` reference was a bit misplaced (And turns it into an XY problem if I'm just looking for an answer to "`typeof` in Rust?") – Nicholas Pipitone Nov 01 '18 at 23:04
  • Then are you looking for [What is the exact definition of the for loop in Rust?](https://stackoverflow.com/q/27224927/155423)? – Shepmaster Nov 01 '18 at 23:07
  • Also related: [What does it mean to pass in a vector into a `for` loop versus a reference to a vector?](https://stackoverflow.com/q/43036279/155423) – Shepmaster Nov 01 '18 at 23:15
  • Argh, SO deleted your comment when I marked it as a duplicate — can you re-comment with the third link you listed? I think it was https://stackoverflow.com/questions/34733811/what-is-the-difference-between-iter-and-into-iter – Shepmaster Nov 02 '18 at 00:53
  • 1
    @Shepmaster Yes, that one was it. – Nicholas Pipitone Nov 02 '18 at 16:17

0 Answers0