scope - 跨多个模块访问单例

标签 scope rust singleton

<分区>

我正在尝试使用 lazy_static crate 创建一个单例并在不同的模块中使用它。这是可能的,甚至是推荐的吗?我仍在学习 Rust 程序应该如何构建,并且一直在使每个文件成为自己的模块。

我在 main.rs 中有以下内容,我可以访问它的值

lazy_static! {
    static ref GAMEDATA: gamedata::data::GameDataS =
        gamedata::data::load_data("./src/assets/data.json".to_string());
}

fn main() {
    println!("data{}", GAMEDATA.width);
}

当尝试访问不同模块中的 GAMEDATA 时,我得到

not found in this scope

例如在名为 game 的模块中

pub struct Game {}
impl Game {
    println!("data{}", GAMEDATA.width);
}

是否可以在所有模块中创建一个全局变量?我应该考虑其他方法吗?也许不经常使用模块?

最佳答案

如果您的静态变量在另一个非父模块中,您的问题似乎是在 static 之前缺少 pub 修饰符。此外,正如其他人指出的那样,您使用变量的代码(impl block )不是有效的 Rust 语法。

除此之外,您还需要使用use 导入静态变量(例如use GAMEDATA;),参见Quan Brew's answer .

但是,我想讨论一下 Rust 中静态和单例模式的使用。

Rust 中的静态变量

在 Rust 中,我们通常避免使用静态变量。在大多数情况下,它们可以通过 const 替换为适当的常量。因为静态变量可以在线程之间共享,所以让它们具有外部可变性在 Rust 中是不安全的。这就是为什么不能使用 lazy_static 实现外部可变性的原因。

虽然具有外部可变性的静态变量确实有它们的用处,但它们是特定的,应该被证明是合理的,否则应该避免。内部可变性,如 this section of the Rust Book 中所述甚至不允许在线程之间共享。

Rust 中的单例模式

我不认为使用 static 来实现单例模式是个好主意。这种模式在 Rust 中并不常见。我们通常将所有可变的东西作为参数传递。

如果您需要不可变数据的解决方案

  1. const让它成为常量。

  2. 如果数据太多,使用static

  3. 如果需要非常量初始化,可以保留lazy_static。

如果你需要改变数据的解决方案

  1. 将您的单例放入Mutex 或其他锁中。这将确保正确的并发访问。

  2. 使用 thread_local macro 使其成为本地线程+ inner mutability with RefCell

  3. 放弃“单例模式”的想法,通过参数传递结构(推荐)。

关于scope - 跨多个模块访问单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52107765/

相关文章:

c++ - 为什么在局部范围内声明一个变量,并放入范围外可见的 vector 中?

javascript - 返回变量值以在另一个函数中使用

testing - 如何设置 RUST_TEST_TASKS 环境变量?

c# - 如何将实例 ninject 传递到构造函数中

Java单例模式在多线程中输出两个相同的对象?

javascript - 为什么我看不到 $scope 函数中定义的 $scope 变量?

c++ - 使部分代码中的变量不可用

string - 如何转换[i8; 88]有点刺耳

rust - 在向量中调用结构的特征方法时出现问题

java - java中的枚举如何线程安全?