さびは奇妙な行動を借りる
以下のrustコードのように:while
ループはコンパイルされて正常に実行for iter
されますが、エラーのためにバージョンはコンパイルされません:
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> src/main.rs:22:9
|
20 | for i in v.iter() {
| --------
| |
| immutable borrow occurs here
| immutable borrow later used here
21 | println!("v[i]: {}", i);
22 | v.push(20);
| ^^^^^^^^^^ mutable borrow occurs here
error: aborting due to previous error
しかし、理解されるように、while
ループにも同じシナリオを持っている、len
とget
して、それが競合しない理由も、immutably借りpush
mutablyボローとして?ここで私の理解が欠けていることを教えてください、啓発してくれてありがとう!
fn main() {
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);
v.push(4);
let mut i = 0;
while i < v.len() && i < 10 {
v.push(20);
println!("v[i]: {:?}", v.get(i));
i += 1;
}
// for i in v.iter() {
// println!("v[i]: {}", i);
// v.push(20);
// }
}
回答
for
コードのバージョンは、次のものとほぼ同等です。
fn main() {
let mut v = Vec::new();
v.push(1);
v.push(2);
v.push(3);
v.push(4);
let mut it = v.iter();
while let Some(i) = it.next() {
println!("v[i]: {}", i);
v.push(20);
}
}
遊び場
それをコンパイルしようとすると、おそらくもう少し意味のあるエラーが発生します。
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> src/main.rs:11:9
|
8 | let mut it = v.iter();
| - immutable borrow occurs here
9 | while let Some(i) = it.next() {
| -- immutable borrow later used here
10 | println!("v[i]: {}", i);
11 | v.push(20);
| ^^^^^^^^^^ mutable borrow occurs here
イテレータはv
ループの全期間にわたって不変に借用しているため、ループ内で変更可能な借用を行うことはできません。
もちろん、それができたとしても、別の項目を追加し続けるため、無限ループになってしまいます。
お電話の際は簡単に言えば、.iter()
あなたはあなたのベクトルを借りて、新しいオブジェクト(イテレータ)、(immutably)を作成し、あなたが実際に借り手段1によって要素の1を与えるループの全体の時間を。一方、を介してアクセスすると、ベクトルから一度に1つの要素を直接借用するため、借用の制限から解放されます。v
.get(i)
push
このような制限の理由は非常に単純です。実際のfor
ループがコンパイルされ、永久に実行されると想像してください(while
ループでこれを防ぐには、人工的な条件を追加する必要がありましたi<10
!)が、これは明らかに意図された目標ではありません(またはそれはあなたが他の方法でそれを明らかにするだろう、例えばwhile let
またはloop
ステートメントで)、そしてあなたが本当にやりたいことをする方法がないので、Rustはあなたが「自分を足で撃つ」のを防ごうとします、そして間違って試みます仕方。
あなたがやりたいことをするために、あなたはすることができます:
for i in 0..v.len() {
v.push(20)
}
なぜなら、v.len()
呼び出しはループv
全体の時間ではfor
なく、最初にのみ借用するからです。