我正在尝试使用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);
}
是否可以在所有模块中创建全局变量?我还有其他思考方式吗?也许不经常使用模块?
答案 0 :(得分:2)
如果您的静态变量在另一个非父模块中,则您的问题似乎是pub
之前缺少的static
修饰符。另外,正如其他人指出的那样,使用变量(impl
块)的代码不是有效的Rust语法。
除此之外,您需要使用use
(例如use GAMEDATA;
)导入静态变量,请参见Quan Brew's answer。
但是,我想讨论一下Rust中静态和单例模式的使用。
在Rust中,我们通常避免使用静态变量。在大多数情况下,可以通过const
将它们替换为适当的常量。由于静态变量可能在线程之间共享,因此在Rust中,使它们具有外部可变性是unsafe
。这就是为什么lazy_static无法具有外部可变性。
尽管具有外部可变性的静态变量确实有其用途,但它们是特定的,应加以说明,否则应避免使用。 this section of the Rust Book中所述的内部可变性甚至不允许在线程之间共享。
我认为使用static具有单例模式不是一个好主意。这种模式在Rust中并不常见。我们通常将所有可变的东西作为参数传递。
使用const
使其恒定。
如果数据太多,请使用static
。
如果需要非恒定初始化,则可以保持lazy_static。
将单身人士放入Mutex
或其他锁中。这将确保正确的并发访问。
放弃“单一模式”的想法,并通过参数传递结构(推荐)。
答案 1 :(得分:0)
您需要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)