如何在 Rust 中创建一个结构体类型的全局变量?

作者站长头像
站长
· 阅读数 19
struct DataItem {
  lv: i32,
  rate: f32,
  fall: Option<i32>,
}

let data : Vec<DataItem> = vec![
  DataItem {
    lv: 1,
    rate: 1.0,
    fall: None,
  },
  DataItem {
    lv: 2,
    rate: 1.0,
    fall: None,
  }
];

我想让 data 是全局变量方便调用而不是在函数中传来传去,但 conststatic 关键字好像都不支持。有什么好办法吗?

回复
1个回答
avatar
test
2024-07-04
如果是下面这种
#[derive(Debug)]
struct DataItem {
  lv: i32,
  rate: f32,
  fall: Option<i32>,
}

const  DATA:[DataItem;2]  = [
  DataItem {
    lv: 1,
    rate: 1.0,
    fall: None,
  },
  DataItem {
    lv: 2,
    rate: 1.0,
    fall: None,
  }
];


fn main() {
    let mut item = &mut DATA[0];
    item.lv = 4;
    println!("{:?}",DATA[0]);
}

遇到的问题是:let mut item = &mut DATA[0]; | ^^^^^^^^^^^^ | = note: each usage of a const item creates a new temporary = note: the mutable reference will refer to this temporary, not the original const item` 如果使用static则不能可变引用DATA,因为DATA item is an immutable static item

换一种方式


static mut DATA:Vec<DataItem> = Vec::new();

#[derive(Debug)]
struct DataItem {
  lv: i32,
  rate: f32,
  fall: Option<i32>,
}


fn main() {
    
  unsafe {
  
     let i = DataItem {
        lv: 1,
        rate: 1.0,
        fall: None,
     };
     DATA.push(i);
     
     let i = DataItem {
        lv: 2,
        rate: 1.0,
        fall: None,
     };
     DATA.push(i);
     
     let mut i  = &mut DATA[0];
     i.lv = 3;
     println!{"{:?}",i};
     
  }
    
   
}

//Output : DataItem { lv: 3, rate: 1.0, fall: None }

把全局变量设置为懒加载(lazy),可在多个线程访问(sync),线程安全(mutex) => 会更好
use std::sync::Mutex;
use once_cell::sync::Lazy;

#[derive(Debug)]
struct DataItem {
    lv: i32,
    rate: f32,
    fall: Option<i32>,
}

static GLOBAL_DATA: Lazy<Mutex<Vec<DataItem>>> = Lazy::new(|| {
    let mut m = Vec::new();
    m.push(
       DataItem {
        lv: 1,
        rate: 1.0,
        fall: None,
     }
    );
    m.push(
      DataItem {
        lv: 2,
        rate: 2.0,
        fall: None,
      }
     );
    Mutex::new(m)
});

fn main() {
    let mut v =  GLOBAL_DATA.lock().unwrap();
    let mut item = &mut v[0];
    item.lv = 4;
    println!("{:?}", item);
}

上面的代码是从once_cell-sync-lazy 抄的 😂 还有更多值得一看

https://docs.rs/once_cell/latest/once_cell/

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容