Hello everyone
I am learning Rust, reading Rust in Action book now (looks good so far btw).
Using Rust 1.53.0 Stable on Windows 10, 64-bit.
I have a minimal code fragment below which puzzles me.
Two questions, please, annotated in // Comments in code
Please ignore the actual logic, its a code fragment based on code in the book I am reading.
fn main() {
let ctx: Vec<Vec<(usize, String)>> = Vec::new();
for local_ctx in ctx.iter() {
for &(i, ref line) in local_ctx.iter() { // QUESTION 1, loop 1, note: & and ref used for tuple here
let line_num = i + 1; // i is usize, no deref needed here, expected
println!("(A){}: {}", line_num, line); // ref line is &String, expected
}
}
for local_ctx in ctx.iter() {
for (i, line) in local_ctx.iter() { // QUESTION 1, loop 2, & and ref removed from tuple, what is best?
let line_num = *i + 1; // QUESTION 2, deref of i, so *i works as expected
let line_number = i + 1; // QUESTION 2, no deref of i, compiles & works correctly, why?
println!("(B){}: {} {}", line_num, line_number, line); // line is &String, even though ref is not used in for loop
}
}
}
More information:
Both loops perform identically re tuple processing so I wonder which tuple binding is more idiomatic Rust
I put // comments in code fragment to help with understanding of my questions.
The FOR loop #1 uses &(i, ref line) and FOR loop 2 uses: (i, line) tuples.
Which is more correct or better use in Rust?
Both return references to &String for line variable but var i is different, it is usize in loop 1, versus &usize in loop 2, that is my question 2 re use of *deref for i.
Question 2: in second loop, i is a &usize, so *i + 1 works, as I expected. What is puzzling for me the following line of code uses i + 1, without *deref for i and it also works correctly. I expected it to give me compilation error (so I am forced to *deref i,) but it appears that in context of for loop both i and *i deref are treated identically. Why so?
Many thanks, I hope I have explained it sufficiently well.