如何在rust中跟踪结构体的示例?

bqf10yzr  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(152)

我有一个简单的游戏实体例子,叫做Nation,它是一个包含所有与玩家资产和活动相关的数据的结构体,玩家可以更改他们的国家名称,这个名称用于登录和轮流使用,因此,玩家必须有一个唯一的标识符,不能更改。
游戏系统中还有其他东西也同样需要唯一标识符,所以对于我的恐龙C大脑来说,显而易见的解决方案是尝试创建一个全局HashMap,将结构体名称作为键,并包含示例计数......然后每当创建新的结构体时,使用当前值作为ID,自动递增该计数器。
Rust真的很讨厌我这样做,这很好。但是,我想学习一种更合适的方法来完成这一点。因为我必须为这些函数实现Default,所以将递增和赋值放在default()函数中似乎是使用它的正确位置,但是计数器本身需要位于那些函数可以访问的地方。
现在,我有这个,很难看,但似乎工作,到目前为止:

static mut nation_id : i64 = 0;

#[derive(Debug)]
struct Nation {
    id          : i64,          // unique naiton ID, established at allocation
    name        : String,       // the nation name, entered at runtime
    // more stuff here...
}

impl Default for Nation {
    fn default() -> Nation {
        unsafe {
            nation_id += 1;
            Nation {
                id: nation_id,          // We want this to actually come from a counter
                name: String::from(""),
                // more stuff here...
            }
        }
    }
}

// World just holds a Vec<Nation> that is initialized to new() and thus empty.

fn main() {
    println!("This is just a test.");
    let mut w : World = Default::default();
    println!("{:?}", w);
    println!("{} nations exist.", w.nations.len());
    let mut n : Nation = Default::default();
    println!("{:?}", n);
    w.nations.push(n);
    println!("{} nations exist.", w.nations.len());
    let mut n2 : Nation = Default::default();
    println!("{:?}", n2);
    w.nations.push(n2);
    println!("{} nations exist.", w.nations.len());
    println!("Test completed.");
}
mlmc2os5

mlmc2os51#

如果你需要一个计数器,一种方法就是使用原子函数。这个函数将返回一个计数器,并且可以同时在多个线程上工作。

use std::sync::atomic::AtomicU64;
use std::sync::atomic::Ordering::SeqCst;

pub fn unique_id() -> u64 {
    static COUNTER: AtomicU64 = AtomicU64::new(0);
    
    COUNTER.fetch_add(1, SeqCst)
}

我们还可以通过强制id必须是唯一的来改进它。

pub fn unique_id() -> u64 {
    static COUNTER: AtomicU64 = AtomicU64::new(0);
    
    let id = COUNTER.fetch_add(1, SeqCst);
    assert_ne!(id, u64::MAX, "ID counter has overflowed and is no longer unique");
    id
}

Rust Playground

相关问题