# 全局变量 在一些场景,我们可能需要全局变量来简化状态共享的代码,包括全局ID,全局数据存储等等,下面我们来一一给出对应的实现方法。 ## 全局唯一ID ```rust use std::sync::atomic::{Ordering, AtomicUsize}; struct Factory{ factory_id: usize, } static GLOBAL_ID_COUNTER: AtomicUsize = AtomicUsize::new(0); // This gives large room for ids to overflow // This code assumes that your app never would need many factories const MAX_ID: usize = usize::MAX / 2; fn generate_id()->usize{ // Check overflow twice to avoid growing of GLOBAL_ID_COUNTER after overflow. let current_val = GLOBAL_ID_COUNTER.load(Ordering::Relaxed); if current_val > MAX_ID{ panic!("Factory ids overflowed"); } let next_id = GLOBAL_ID_COUNTER.fetch_add(1, Ordering::Relaxed); if next_id > MAX_ID{ panic!("Factory ids overflowed"); } next_id } impl Factory{ fn new()->Self{ Self{ factory_id: generate_id() } } } ``` ## 从函数中返回全局变量 https://www.reddit.com/r/learnrust/comments/rqn74g/cant_a_function_return_a_reference_to_some_global/ ## lazy_static ```rust use std::{sync::{Mutex, MutexGuard}, thread}; use std::thread::sleep; use std::time::Duration; use lazy_static::lazy_static; lazy_static! { static ref MUTEX1: Mutex = Mutex::new(0); static ref MUTEX2: Mutex = Mutex::new(0); } fn main() { // Spawn thread and store handles let mut children = vec![]; for i_thread in 0..2 { children.push(thread::spawn(move || { for _ in 0..1 { // Thread 1 if i_thread % 2 == 0 { // Lock mutex1 // No need to specify type but yes create a dummy variable to prevent rust // compiler from being lazy let _guard: MutexGuard = MUTEX1.lock().unwrap(); // Just log println!("Thread {} locked mutex1 and will try to lock the mutex2, after a nap !", i_thread); // Here I sleep to let Thread 2 lock mutex2 sleep(Duration::from_millis(10)); // Lock mutex 2 let _guard = MUTEX2.lock().unwrap(); // Thread 2 } else { // Lock mutex 1 let _guard = MUTEX2.lock().unwrap(); println!("Thread {} locked mutex2 and will try to lock the mutex1", i_thread); // Here I freeze ! let _guard = MUTEX1.lock().unwrap(); } } })); } // Wait for child in children { let _ = child.join(); } println!("This is not printed"); } ``` ## box::leak