2017-12-11 16 views
7

私は錆ブックの第二版を読んでいると私は、イテレータセクションに次のサンプルを見つけました:なぜコンパイラはforループに移動したイテレータが不変であると不平を言っていませんか?

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

なぜコンパイラはv1_iterが不変であることを文句ないのですか?この本は、forループがv1_iterの所有権を持ち、舞台裏で可変にしていると言いますが、不変の変数を可変に変換できますか?

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

注意こと:

答えて

9

本は、forループv1_iterの所有権を取り、舞台裏、それは可変作られ、

正確に、かつ1は、さらに簡単な例を作ることができると言いますvxは別々の変数バインディングです。変数vが3要素のベクトルを保持している限り、変数のコントラクトはそのベクトルが変更されないということでした。しかし、ベクトルはxに移動しました。これは可変性が許容可能であると宣言します。

fn foo(mut x: Vec<i32>) { 
    x.push(0); 
} 

let v = vec![1,2,3]; 
foo(v); 

これは、変数の1つだけがそのライフタイムの任意の時点でベクトルを所有しているため安全です。 vxに移動されると、vはもはや使用できません。同様に、あなたのコードでは、v1_iterはforループの後で使用することはできません。

しかし、不変の変数を可変に変換できますか?

両方のスニペットは、値がmutと宣言された新しい変数に移動されたために機能します。しかし、いったん変数が不変(または変更可能)として宣言されると、その変数はすべての存続期間にわたってそのままであり、変更することはできません。したがって、答えは「いいえ」ですが、所有権のセマンティクスによって、異なる可変性保証を持つ変数間で値を移動できます。

関連する問題