当前位置: 首页 > 知识库问答 >
问题:

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

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

共有2个答案

陶刚豪
2023-05-04

用 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);
    }
}
谭景福
2023-05-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/

 类似资料:
  • 使用和不起作用。有没有别的办法我可以打印号码的类型?

  • 语法问题。 已有代码 想请问下,impl Display for Point<T> 正确写法是啥样的?

  • 我的问题分为两个部分(因为我不能得到第一部分,我移到了第二部分,这仍然让我有疑问) 第1部分:如何将异构类型插入?起初我想通过来完成 例如。, 但是我得到了一个错误 第2部分:然后我去了文档并阅读了《使用允许不同类型值的特征对象》,并将问题简化为只是尝试将异构类型放入中。所以我完全按照教程进行操作,但我仍然会收到相同类型的错误(在文档的情况下,错误现在是。 我知道静态类型是Rust的重要组成部分,

  • 本文向大家介绍Rust 结构域,包括了Rust 结构域的使用技巧和注意事项,需要的朋友参考一下 示例 这指定任何给定的实例Struct具有生命周期'a,并且&u32存储在x中的生命周期必须至少为'a。

  • 我正在尝试将一个旧的个人Java项目转换为Rust,作为一种学习体验。基本数据结构如下所示: 有一个主要的。有作者列表和书籍列表 每个作者都有一份他/她写过的书的清单 每本书都有作者的参考资料 在Java程序中,我决定程序中的每本书(“霍比特人”)不应该存在多个对象。如果一本新书(可能通过用户输入)进入系统,我要做的第一件事是测试它是否已经在,然后用

  • 问题内容: 在我的android应用程序中,我需要放置可变成员id的位置。问题是,它是从在线API获取的,我需要找到一种存储/检索它的方法 我尝试将其放在自定义类中,但是问题是,如果我取消活动,它将丢失,我还知道有一种方法可以扩展应用程序。 所以我想知道存储全局变量的最佳方法是什么? 我必须实现: 将变量保存在onSaveState上 将其保存在sharepref 手动保存 手动检索 谢谢 更新: