2016-03-05 74 views
8

我注意到Rust的Atomic*結構具有修改該值的功能,例如fetch_add。舉例來說,我可以這樣寫程序:爲什麼Rust的`Atomic *`類型使用非可變函數來改變該值?

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(); 
} 

這編譯和運行正常,但如果我改變AtomicUsize正常整數,它會(正確地)無法編譯由於可變性的擔憂:

struct Tester { 
    counter: u64 
} 

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

除了Chris Morgans的回答:你可以在官方的'std'文檔(https://doc.rust-lang.org/std/cell/index.html)上看到所謂的內部可變性。 'RefCell'是另一個例子。 –

回答

11

如果它沒有這樣工作,它不會很有用。在&mut引用中,一次只能存在一個,並且當時沒有引用&,所以操作的原子性的整個問題都是沒有意義的。

看它的另一種方式是&mut獨特參考,並&aliasable引用。對於正常類型,如果您有唯一的引用,則只能安全地進行突變,但原子類型都是關於突變(通過替換)而不需要唯一引用。

&&mut的命名一直是一個充滿憂慮的事情,在社區和文件中有很多恐懼,不確定和疑問,像Focusing on Ownership解釋事實如何。該語言結束了與&&mut,但&mut實際上是關於唯一性而不是可變性(它只是大多數時候兩者是等價的)。

相關問題