2016-03-05 20 views
8

Rust'un Atomic* yapısının fetch_add gibi değeri değiştiren işlevlere sahip olduğunu fark ettim.Rust'un `Atomic *` türleri neden değeri değiştirmek için değiştirilemeyen işlevler kullanıyor?

use std::sync::atomic::{AtomicUsize, Ordering}; 

struct Tester { 
    counter: AtomicUsize 
} 

impl Tester { 
    fn run(&self) { 
     let counter = self.counter.fetch_add(1, Ordering::Relaxed); 
     println!("Hi there, this has been run {} times", counter); 
    } 
} 

fn main() { 
    let t = Tester { counter: AtomicUsize::new(0) }; 
    t.run(); 
    t.run(); 
} 

Bu derler ve iyi çalışır, ancak ben normal tamsayıya AtomicUsize değiştirirseniz, bu (doğru) nedeniyle mutability endişeleri derlemek başarısız olur:

struct Tester { 
    counter: u64 
} 

impl Tester { 
    fn run(&self) { 
     self.counter = self.counter + 1; 
     println!("Hi there, this has been run {} times", self.counter); 
    } 
} 
Mesela ben bu programı yazabilir
+2

Chris Morgans'a ek olarak, cevap: iç mekanın mutabilitesini [resmi 'std' belgelerinde] okuyabilirsiniz (https://doc.rust-lang.org/std/cell/index.html). 'RefCell' başka bir örnektir. –

cevap

11

Bu şekilde çalışmazsa çok kullanışlı olmaz. &mut referansları ile, bir seferde yalnızca bir tane var olabilir ve o zaman & referansı yoktur, bu nedenle operasyonun atomikliği ile ilgili bütün soru tartışmalıdır.

bakarak bir başka yolu &mutbenzersiz referanslar ve &aliasable referanslarıdır olduğunu. Normal tipler için, mutasyon, sadece benzersiz bir referansınız varsa, güvenli bir şekilde meydana gelebilir, ancak atomik tiplerin hepsi, tek bir referansa gerek duymadan, mutasyon (değiştirme yoluyla) ile ilgilidir.

& ve &mut isimlendirilmesi kadar korku, belirsizlik ile, bir dolu mesele olmuştur ve toplumda şüphe ve belgeler gibi Focusing on Ownership şeyler aslında ne kadar açıklanması bağlamında. Bu dil, & ve &mut ile kalmaya devam etti, ancak &mut aslında mutabiliteden ziyade teklikle ilgilidir (sadece iki eşdeğerdir).

İlgili konular