rust如何定义全局对象变量

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

解决方式:

rust 复制代码
#[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

换一种方式

rust 复制代码
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};
     
  }
    
}
把全局变量设置为懒加载(lazy),可在多个线程访问(sync),线程安全(mutex) => 会更好
rust 复制代码
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);
}

还有提供的解决方案:

let 关键字不能在全局范围内使用。我们只能使用staticconst 。后者声明的是一个真正的常量,而不是一个变量。只有static 给我们一个全局变量。

这背后的原因是,let 在运行时在堆栈上分配了一个变量。请注意,当在堆上分配时,这仍然是真实的,如let t = Box::new(); 。在生成的机器代码中,仍然有一个指向堆的指针,它被存储在堆上。

全局变量被存储在程序的数据段中。它们有一个固定的地址,在执行过程中不会改变。因此,代码段可以包括常数地址,并且完全不需要堆栈中的空间。

好了,我们可以理解为什么我们需要一个不同的语法。Rust作为一种现代系统编程语言,希望在内存管理方面非常明确

定义全局变量

在 Rust 中,定义全局变量需要使用static关键字。定义全局变量的方式有两种:

定义不可变的全局变量

static GLOBAL_VAR: i32 = 42;

在上述代码中,我们定义了一个名为GLOBAL_VAR的全局变量,类型为i32,初始值为42。需要注意的是,定义的全局变量必须指定类型。在定义不可变的全局变量后,我们可以在程序的任何地方读取它的值。

定义可变的全局变量

static mut GLOBAL_VAR: i32 = 42;

在上述代码中,我们使用static mut定义了一个名为GLOBAL_VAR的可变全局变量,类型为i32,初始值为42。需要注意的是,定义可变的全局变量必须使用mut关键字,并且在使用可变全局变量时需要使用unsafe关键字。

全局变量的安全性

在 Rust 中,全局变量的使用需要特别注意并发安全性问题。由于全局变量可以在程序的任何地方使用,因此可能会引起数据竞争等问题。为了解决这些问题,Rust 提供了一些特殊的机制来确保全局变量的安全性。

一种常用的方法是使用MutexRwLock等同步机制。

示例:

rust 复制代码
use std::sync::Mutex;

static mut TABLE: Mutex<Table> = Mutex::new(Table::new());

type Table = Vec<Entry>;

#[derive(Debug)]
#[allow(dead_code)]
struct Entry {
    key: i32,
    value: i32,
}

fn main() {
    let mut table = unsafe { TABLE.lock().unwrap() };
    // let mut entry = Entry { key: 1, value: 10 };
    *table = vec![Entry { key: 1, value: 10 }];
    println!("table: {:?}", table);
}

述代码演示了如何在 Rust 中定义可变的全局变量。

首先,我们使用 use 关键字导入了 std::sync::Mutex,这是 Rust 中的一种同步机制。接着,我们使用 static mut 关键字定义了一个名为 TABLE 的可变全局变量,类型为 Mutex<Table>。在 Rust 中,使用 Mutex 来保护共享数据的并发安全性是一种常用的方式。

main() 函数中,我们获取了 TABLE 的锁,并将其值修改为一个包含一个 EntryVec。需要注意的是,在使用可变全局变量时,必须使用 unsafe 关键字,最后,我们打印出了修改后的 TABLE 的值。

全局变量的使用需要特别注意并发安全性问题。由于全局变量可以在程序的任何地方使用,因此可能会引起数据竞争等问题。为了解决这些问题,Rust 提供了一些特殊的机制来确保全局变量的安全性,例如 MutexRwLockAtomicChannel 等。在使用全局变量时,我们需要根据实际情况选择合适的同步机制,以确保程序的并发安全性。

其他用法参考地址:
在 Rust 中使用全局变量

ArchGrid - 架构知识网格 - Rust惑点启示系列(七):使用全局变量和单例

相关推荐
杨荧29 分钟前
基于Python的电影评论数据分析系统 Python+Django+Vue.js
大数据·前端·vue.js·python
anlogic42 分钟前
Java基础 8.16
java·开发语言
excel1 小时前
迭代器与生成器全面理解
前端
可口码农1 小时前
MixOne:Electron Remote模块的现代化继任者
java·前端·electron
发如雪-ty1 小时前
Bash常用操作总结
前端·chrome
蚰蜒螟1 小时前
Netty 的 Select/Poll 机制核心实现主要在 NioEventLoop 的事件循环
java·开发语言
冲!!1 小时前
使用nvm查看/安装node版本
前端·node.js·node·nvm
LilyCoder2 小时前
HTML5二十四节气网站源码
前端·javascript·html·html5
野生的编程萌新2 小时前
从冒泡到快速排序:探索经典排序算法的奥秘(二)
c语言·开发语言·数据结构·c++·算法·排序算法
Full Stack Developme2 小时前
Java后台生成多个Excel并用Zip打包下载
java·开发语言·excel