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

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 关键字好像都不支持。有什么好办法吗?

阅读 3.5k
2 个回答
如果是下面这种
#[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/

用 lazy_static 宏:


use std::sync::Mutex;
use lazy_static::lazy_static;

struct DataItem {
    lv: i32,
    rate: f32,
    fall: Option<i32>,
}

lazy_static! {
    static ref DATA: Mutex<Vec<DataItem>> = Mutex::new(vec![
        DataItem {
            lv: 1,
            rate: 1.0,
            fall: None,
        },
        DataItem {
            lv: 2,
            rate: 1.0,
            fall: None,
        },
    ]);
}
fn main() {

    {
        let data = DATA.lock().unwrap();
        println!("data[0].lv: {}", data[0].lv);
    }

    {
        let mut data = DATA.lock().unwrap();
        data[0].lv = 3;
    }

    {
        let data = DATA.lock().unwrap();
        println!("data[0].lv: {}", data[0].lv);
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏