也不是全局可变变量安全
你的C++例子似乎将具有线程安全性问题,但我不知道够不够C++是肯定的。
但是,只有不同步全局可变变量是麻烦。如果你不关心跨线程的问题,你可以使用一个线程局部:
use std::cell::Cell;
#[derive(Debug)]
struct Monster {
id: usize,
health: u8,
}
thread_local!(static MONSTER_ID: Cell<usize> = Cell::new(0));
impl Monster {
fn new(health: u8) -> Monster {
MONSTER_ID.with(|id| {
let id_val = id.get();
id.set(id_val + 1);
Monster { id: id_val, health: health }
})
}
}
fn main() {
let gnome = Monster::new(41);
let troll = Monster::new(42);
println!("gnome {:?}", gnome);
println!("troll {:?}", troll);
}
如果你想要的东西,多线程工作得更好,检查出lazy_static crate。
注意bluss' answer展示了如何使用原子没有 lazy_static,是这种情况好得多。 lazy_static是更广泛的使用,所以在这里我要离开这个例子现在
#[macro_use]
extern crate lazy_static;
use std::sync::atomic::{AtomicUsize, Ordering};
#[derive(Debug)]
struct Monster {
id: usize,
health: u8,
}
lazy_static!{
static ref MONSTER_ID: AtomicUsize = AtomicUsize::new(0);
}
impl Monster {
fn new(health: u8) -> Monster {
let id = MONSTER_ID.fetch_add(1, Ordering::SeqCst);
Monster { id: id, health: health }
}
}
fn main() {
let gnome = Monster::new(41);
let troll = Monster::new(42);
println!("gnome {:?}", gnome);
println!("troll {:?}", troll);
}
啊,我总是忘了,你可以静态初始化一个原子,干净多了! – Shepmaster
我以为我应该是建设性的,而不是只挑选一次在SO上发表评论。不知道它是否成功。虽然这是例子。 :) – bluss
那么,在这种情况下添加答案总是一个更好的主意。越来越多的人会这样看待它,如果它更好,它最终可以获得高于其他答案的票数。此外,您通过这种方式获得更多积分,并且每个人都喜欢积分! – Shepmaster