Why doesn't the compiler complain that the iterator moved to the for loop is immutable?

I am reading the second edition of Rust Book, and I found the following example in the iterator section:

let v1 = vec![1, 2, 3]; let v1_iter = v1.iter(); for val in v1_iter { println!("Got: {}", val); } 

Why does the compiler not complain that v1_iter immutable? The book says that the for loop took the responsibility of v1_iter and made it mutable behind the scenes, but can you convert an immutable variable to a mutable one?

+7
move-semantics rust
source share
1 answer

The book says the for loop took charge of v1_iter and made it mutable behind the scenes,

Exactly, and you can make an even simpler example:

 let v = vec![1,2,3]; let mut x = v; x.push(0); 

Note that v and x are separate variable bindings: as long as the variable v retains our three-element vector, the contract for the variable was that the vector would not be mutated. However, the vector has been ported to x , which states that variability is acceptable. The same applies to function calls:

 fn foo(mut x: Vec<i32>) { x.push(0); } let v = vec![1,2,3]; foo(v); 

This is safe because only one of the variables owns the vector anywhere in its life. When v was ported to x , v can no longer be used. Similarly, in your code, v1_iter can no longer be used after a for loop.

but can you convert an immutable variable to mutable?

Both fragments work because the value has been transferred to a new variable declared as mut . However, as soon as a variable is declared immutable (or mutable), this variable remains the same for its entire life cycle and which cannot be changed. Thus, the answer is no, but the semantics of ownership allow you to move values ​​between variables with different guarantees of mutability.

+12
source share

All Articles