Rust ödünç alır garip davranışlar
Aşağıdaki pas kodu gibi: whiledöngü derler ve iyi çalışır, ancak for itersürüm hata nedeniyle derlenmez:
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
Ama anlaşılan olarak, whiledöngü de aynı senaryoyu sahiptir lenve getbirlikte o çakışmayan neden de, immutably ödünç pushmutably borrow olarak? Lütfen burada eksik olan anlayışımın ne olduğunu söyleyin, aydınlatıcı için çok teşekkür ederim!
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);
// }
}
Yanıtlar
forKodunuzun versiyonu aşağıda kabaca eşittir:
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);
}
}
Oyun alanı
Bunu derlemeye çalışırsanız, belki biraz daha mantıklı bir hata alırsınız:
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
Yineleyici, vdöngünün tüm süresi boyunca değişmez bir şekilde ödünç alıyor, bu nedenle döngü içinde herhangi bir değiştirilebilir ödünç alamazsınız.
Tabii ki, bunu yapabilseniz bile, sonsuz bir döngü elde edersiniz çünkü başka bir öğe eklemeye devam edersiniz.
Sadece çağrı yaparken, koyun .iter(), siz (immutably) vektör ödünç (bir yineleyici), yeni nesneler oluşturmak ve aslında ödünç demektir birer eleman birini verir döngünün bütün zaman . Öte yandan, sizin aracılığınızla eriştiğinizde, doğrudan vektörden bir elementi ödünç alırsınız ve böylece, ödünç alma kısıtlamalarından kurtulmuş olursunuz .v.get(i)push
Bu tür bir kısıtlamanın nedeni çok basit: gerçek fordöngünüzün derlendiğini ve sonsuza kadar çalışacağını hayal edin (ve bunu whiledöngüde önlemek için yapay koşulu eklemeniz gerekir i<10!), Oysa bu açıkça amaçlanan hedef değil (veya aksi takdirde bunu açıkça yaparsınız, örneğin bir while letveya loopifadeyle) ve Rust, "kendinizi bacağınıza vurmanızı" engellemeye çalışır çünkü yapmak istediğiniz şeyi gerçekten nasıl yapacağınızı bilmiyorsunuz ve yanlışı denemiyorsunuz yol.
Yapmak istediğiniz şeyi yapmak için şunları yapabilirsiniz:
for i in 0..v.len() {
v.push(20)
}
çünkü v.len()çağrı vtüm fordöngünün süresi boyunca değil, yalnızca başlangıçta ödünç alır .