跨多个模块访问单例[重复]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨多个模块访问单例[重复]相关的知识,希望对你有一定的参考价值。
我正在尝试使用lazy_static包来创建单例并在不同的模块中使用它。这是可能的,甚至是推荐的吗?我还在学习如何构建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
时,我得到了
在此范围内未找到
例如,在一个名为game
的模块中
pub struct Game {}
impl Game {
println!("data{}", GAMEDATA.width);
}
是否有可能在所有模块中创建一个全局变量?还有其他方法我应该考虑一下吗?也许不经常使用模块?
如果你的静态变量在另一个非父模块中,你的问题似乎是在pub
之前缺少static
修饰符。另外,正如其他人所指出的,使用变量(impl
块)的代码不是有效的Rust语法。
除此之外,您还需要使用use
(例如use GAMEDATA;
)导入静态变量,请参阅Quan Brew's answer。
但是,我想讨论在Rust中使用静态和单例模式。
Static variables in Rust
在Rust中,我们通常避免使用静态变量在大多数情况下,他们可以通过const
替换为适当的常数。因为静态变量可以在线程之间共享,所以具有外部可变性的是Rust中的unsafe
。这就是为什么你不能使用lazy_static进行外部可变性的原因。
虽然具有外部可变性的静态确实有它们的用途,但它们是特定的,应该是合理的,否则就应该避免。如this section of the Rust Book中所描述的内部可变性甚至不允许在线程之间共享。
Singleton Pattern in Rust
我不认为使用静态来获得单例模式是个好主意。这种模式在Rust中并不常见。我们通常将所有可变的东西作为参数传递。
Solutions if you need immutable data
- 用
const
使它成为一个常数。 - 如果数据太多,请使用
static
。 - 如果需要非常量初始化,可以保持lazy_static。
Solutions if you need to mutate data
- 把你的单身人士放入
Mutex
或其他锁。这将确保正确的并发访问。 - 使用thread_local macro + inner mutability with RefCell使其成为局部线程
- 放弃“单身模式”的想法,并通过参数传递结构(推荐)。
您需要use
将GAMEDATA
导入当前范围,如modules section in the book中所述。
示例代码(playground):
#[macro_use]
extern crate lazy_static; // 1.1.0
lazy_static! {
static ref GAMEDATA: String = "hello".to_string();
}
mod foo {
use GAMEDATA;
pub fn bar() {
println!("{}", *GAMEDATA);
}
}
fn main() {
foo::bar();
}
但是,Rust中不建议使用单例模式。对于初学者来说,在学习阶段,你最好避免单身。 (见bzim's answer)
以上是关于跨多个模块访问单例[重复]的主要内容,如果未能解决你的问题,请参考以下文章