2015-05-20 5 views
5

Если я хочу, чтобы потреблять итератор вручную, он должен быть изменяемым:Почему цикл for не требует изменчивого итератора?

let test = vec![1,2,3]; 
let mut test_mut = test.iter(); 
while let Some(val) = test_mut.next() { 
    println!("{:?}",val); 
} 

Но я могу с удовольствием потреблять его для цикла, даже если это неизменное.

let test_imm = test.iter(); 
for val in test_imm { 
    println!("{:?}",val); 
} 

Я думаю это примерно работает, потому что test_imm перемещается в течение тела цикла, поэтому test_imm не может быть использован внешним блоком не больше, и (с точки зрения внешнего блока) неизменяемый до цикла for, а затем он недоступен, так что все в порядке.

Это правильно? Есть ли еще объяснение?

Ред.: Ага, это более или менее объяснено. here.

ответ

7

Это точно. Так как он перемещен в цикл for, цикл for теперь принадлежит ему и может делать с ним все, что захочет, включая «make it» mutable. Рассмотрим этот аналогичный пример, где мы, кажется, мутируем xs, несмотря на то, что он неизменен, но на самом деле это потому, что мы его перемещаем, поэтому новый владелец имеет право делать с ним все, что захочет, включая повторное связывание его как изменчивое:

let xs: Vec<i32> = vec![1, 2, 3]; 

fn append(v: Vec<i32>, x: i32) -> Vec<i32> { 
    let mut my_v = v; 
    my_v.push(x); 
    my_v 
} 

let appended = append(xs, 4); 

playpen

Обратите внимание, что эта функция может быть короче, используя mut параметр удобства синтаксис:

fn append(mut v: Vec<i32>, x: i32) -> Vec<i32> { 
    v.push(x); 
    v 
}