2017-07-27 19 views
5

Borç denetleyicisinden bir Rust derleme hatası alıyorum ve nasıl düzeltileceğini bilmiyorum.
Aşağıdaki kod C++ 'da basittir ve benzer kodlarda sorun yoktur. Sen bekçi fıkrada atıf KQUEUE olabilirBu basit kod ile Rust borç kontrolü nasıl karşılanır?

message: 'cannot borrow `nums` as mutable because it is also borrowed as immutable (4, 9)' 
+1

, bu nums durumu gibi olabilir nums.last() değeri olarak num.push() ile aynı ifadede .last(), sayıya yeni bir giriş iterken değişebilir. – jwenting

cevap

4

:

fn main() { 
    let mut nums = vec![1, 2, 3]; 
    if let Some(&x) = nums.last() { 
     nums.push(x); 
    } 
} 

Pas özelliğini eşleşen güçlü modeli vardır, neredeyse her şeyi eğer paketten İşte

fn main() { 
    let mut nums = vec![1, 2, 3]; 
    if let Some(x) = nums.last() { 
     nums.push(*x); 
    } 
} 

hatadır onun türünü biliyorsun. Rust pattern matching documentation'u kontrol edin.

+0

Teşekkürler, işe yarıyor. Nums.last() nums.push() ile çakıştığını düşündüm. Rust belgesi, "referans açmayı" nı ayrıntılı olarak açıklıyor? – LiLei

+0

@LiLei, Cevabı güncelledim, pasla ilgili tüm eşleme özelliklerine (bal gibi tatlı) bir göz atmalısınız;) – Netwave

7

.last() numaralı telefonu aradığınızda, nums kodunu immutable olarak ödünç alırsınız, mutasyona uğrattığınız gibi, tuttuğunuz şekilde x referansını geçersiz kılar. Ardından, nums'u mutable olarak ödünç veren .push numaralı telefonu arayın.

sorun artık bir değişmez ve (paslanmayan hafıza güvenlik teminatı aykırıdır aynı anda aynı değerde bir değişken ödünç olması birden okuyucular veya geçersiz hafızaya sahip asla tek yazar garantisi herhangi bir yer).

fn main() { 
    let mut nums = vec![1, 2, 3]; 
    if let Some(x) = nums.last() { // Immutable borrow starts here 
     nums.push(*x);    // Mutable borrow starts here 
    }        // Immutable and mutable borrows end here 
} 

çözeltisi @ DanielSanchez örneğinde göre, derhal sonucun referans bırakarak değişmez borç ile kapsamını daha düşük olacaktır: Rust bilmeden

let mut nums = vec![1, 2, 3]; 
if let Some(&x) = nums.last() { // Immutable borrow starts and ends here 
    nums.push(x);    // Mutable borrow starts here 
}        // Mutable borrow ends here 
+0

Teşekkürler, bu cevap daha net. Sadece değişmez borçların hayatının neden bitmediğini bilmiyordum. Şimdi biliyorum nedeni nums.last() döndürülen değeri başvuru. Ama neden "& x" denilemez borçlanmayı sona erdirebilir? Bu bağlamda – LiLei

+2

, '& x' aslında dereferences x'. Normalde, bu x'yi hareket ettirir, ancak tamsayılar 'Kopya 'özelliğini kullanırlar, yani' x' sözcüğünü hareket ettirmek yerine, x'in otomatik olarak oluşturulmuş bir kopyası ile çalışırız. 'X' dereferencing '.last() 'tarafından döndürülen referansı yok eder ve neden olduğu borçlanmayı sonlandırır. –