创建和使用系统中只有一个实例化的结构体的最佳方法是什么?是的,这是必要的,它是 OpenGL 子系统,制作它的多个副本并将其传递到各处会增加混乱,而不是缓解混乱。
单例需要尽可能高效。似乎不可能在静态区域上存储任意对象,因为它包含Vec带有析构函数的对象。第二个选项是在静态区域上存储一个(不安全)指针,指向堆分配的单例。在保持语法简洁的同时,最方便、最安全的方法是什么?
在 Rust 中创建只有一个实例的结构体最常见的方法是使用 lazy_static crate 来实现惰性静态初始化。这样可以确保结构体只会在首次访问时被初始化,并且在整个程序运行期间只会初始化一次。
lazy_static
下面是一个示例,演示了如何使用 lazy_static crate 创建单例结构体:
首先,将 lazy_static crate 添加到你的 Cargo.toml 文件中:
Cargo.toml
[dependencies] lazy_static = "1.4"
然后,你可以按照以下方式在代码中使用:
use lazy_static::lazy_static; use std::sync::Mutex; // 定义一个结构体,用于存储 OpenGL 子系统的状态或数据 struct OpenGLSubsystem { // 这里可以包含你需要的任何状态或数据 } // 使用 lazy_static 宏定义一个静态的 Mutex,用于包裹 OpenGLSubsystem 结构体的可变引用 lazy_static! { static ref OPENGL_SUBSYSTEM: Mutex<OpenGLSubsystem> = Mutex::new(OpenGLSubsystem { /* 初始化状态或数据 */ }); } // 现在,你可以在代码的任何地方通过访问 OPENGL_SUBSYSTEM 获取 OpenGL 子系统的实例 fn main() { // 获取 OpenGL 子系统的实例 let mut opengl = OPENGL_SUBSYSTEM.lock().unwrap(); // 现在你可以在 opengl 上调用方法,对其进行操作 // 例如: // opengl.some_method(); // 注意:由于 OPENGL_SUBSYSTEM 是一个 Mutex,需要在使用之前获取锁 // 使用完毕后,锁会在作用域结束时自动释放 }
在上面的代码中,OPENGL_SUBSYSTEM 是一个 Mutex 包裹的 OpenGLSubsystem 结构体的静态变量。通过 lazy_static! 宏,我们确保 OPENGL_SUBSYSTEM 只会在首次访问时被初始化,而且在整个程序运行期间只会初始化一次。在使用之前,我们需要获取 OPENGL_SUBSYSTEM 的锁,并在作用域结束时释放锁。
OPENGL_SUBSYSTEM
Mutex
OpenGLSubsystem
lazy_static!