2016-03-05 1 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の参照では、一度に1つしか存在することができず、その時点では&の参照がないため、操作の原子性の問題全体が疑わしいものになります。

それを見て別の方法がある&mutユニーク参照、&aliasable参照です。通常の型では、一意の参照がある場合にのみ、突然変異が発生することがありますが、一意の参照を必要とせずに、原子型はすべて置換に関するものです。

&&mutの命名は非常に恐れ、地域社会における不確実性と疑い、物事が実際にどのように説明するFocusing on Ownershipのような文書で、はらんで問題となっています。言語は&&mutで終わってしまいましたが、&mutは、実際には可変性ではなく一意性です(2つが同等であることがほとんどです)。