2 个版本
0.1.1 | 2022年7月21日 |
---|---|
0.1.0 | 2022年7月20日 |
#2652 in Rust 模式
20KB
204 行
一个用于静态单次安全初始化,无开销的库。
Rust 中初始化静态有几种方法。最常见的是 lazy_static
或 once_cell
,后者甚至被集成到标准库中。[链接](https://doc.rust-lang.net.cn/nightly/std/cell/struct.LazyCell.html)。这些库会延迟初始化值。问题是,这会为每次访问带来开销,虽然开销很小,但对于某些应用程序来说,这是一个问题。
此库提出了另一种方法:初始化产生一个零大小访问令牌,然后您可以使用该令牌通过 Deref
访问值。
实现该功能有两种方式:[代码宏](https://docs.rs/init-token/latest/init_token/macro.init.html) init!
和 init_big!
。建议使用 init!
作为默认选项。其语法如下:
init_token::init! {
/// The magic token to get `MY_STATIC` working.
pub token MyInitToken;
/// My cool static.
pub static MY_STATIC: i32 = std::env::var("MY_STATIC").unwrap().parse().unwrap();
}
init_big!
适用于静态值非常大,太大以至于无法在栈上传递的情况,从而使得从初始化器返回它成为问题。相反,您提供一个常量初始化器,然后使用 init(name) { init_code }
,其中 name
将是静态内容的可变引用。以下示例将更好地解释:
init_token::init_big! {
/// The magic token to get `MY_STATIC` working.
pub token MyInitToken;
/// My cool static.
// The initializer here must be `const` and will be put directly on the `static`'s
// initializer expression.
pub static MY_STATIC: i32 = 0;
// Now, we write code to calculate the static and assign to it as we wish.
// `my_static` here is a pointer to `MY_STATIC` and has the type `&mut i32`.
init(my_static) {
*my_static = std::env::var("MY_STATIC").unwrap().parse().unwrap();
}
}
使用init!
,静态变量将是一个 init::Static
的实例。使用 init_big
,它将是一个 init_big::Static
的实例。在这两种情况下,您都应该在静态变量上调用 init()
方法来获取访问令牌。令牌将是一个自动生成的结构体,它实现了 Deref
到静态变量类型的接口。如果您需要 'static
引用,可以使用关联函数 static_ref()
(它不是一个方法 - 调用方式为 TokenType::static_ref(token)
,而不是 token.static_ref()
)!
静态变量和令牌的可见性不必匹配。如果您想控制谁可以获取令牌,但又希望一旦他们有了令牌,所有人都可以使用静态变量,而不需要携带非零大小的静态变量的引用,这可能很有用。