Desugared sürümü sahip olduğunuzdan biraz farklı. Çizgi
v[v[1]] = 999;
aslında desugarlar
*IndexMut::index_mut(&mut v, *Index::index(&v, 1)) = 999;
Bu aynı hata iletisiyle sonuçlanır, ancak ek açıklamalar neler olduğuna dair bir ipucu verir:
error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
--> src/main.rs:7:48
|
7 | *IndexMut::index_mut(&mut v, *Index::index(&v, 1)) = 999;
| ------------------- ------ ^^ immutable borrow occurs here
| | |
| | mutable borrow occurs here
| mutable borrow later used by call
Desugared versiyonunuzdaki önemli fark değerlendirme sırasıdır. Bir işlev çağrısının bağımsız değişkenleri, aslında işlev çağrısı yapılmadan önce, soldan sağa listelenen sırada değerlendirilir. Bu durumda bu &mut v
, öncelikle borçlanmanın mutabil olarak değerlendirildiği anlamına gelir v
. Sonra, Index::index(&v, 1)
değerlendirilmelidir, ancak bu mümkün değildir - v
zaten mutably ödünç alınmıştır. Son olarak, derleyici işlev çağrısı için değiştirilebilir başvurunun hala gerekli olduğunu gösterir index_mut()
, bu nedenle paylaşılan başvuru denendiğinde değiştirilebilir başvuru hala canlıdır.
Aslında derleyen sürümün biraz farklı bir değerlendirme sırası vardır.
*v.index_mut(*v.index(1)) = 999;
İlk olarak, yöntem çağrılarına yönelik işlev argümanları soldan sağa, yani *v.index(1)
önce değerlendirilir. Bu a ile sonuçlanır usize
ve geçici ortak borcu v
tekrar serbest bırakılabilir. Daha sonra, alıcısı index_mut()
değerlendirilir, yani v
mutabakatla ödünç alınır. Paylaşılan borç zaten sonlandırıldığından ve tüm ifade borç kontrolünden geçtiği için bu işe yarar.
Sadece "sürümsel olmayan yaşam" lansmanından bu yana derleme sürümü bunu unutmayın. Rust'un önceki sürümlerinde, paylaşılan borç ifadenin sonuna kadar yaşayacak ve benzer bir hatayla sonuçlanacaktır.
Bence en temiz çözüm geçici bir değişken kullanmaktır:
let i = v[1];
v[i] = 999;