#static #token #init

init-token

一个用于静态单次安全初始化,无开销的库。

2 个版本

0.1.1 2022年7月21日
0.1.0 2022年7月20日

#2652 in Rust 模式

MIT 许可证

20KB
204

一个用于静态单次安全初始化,无开销的库。

Rust 中初始化静态有几种方法。最常见的是 lazy_staticonce_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())!

静态变量和令牌的可见性不必匹配。如果您想控制谁可以获取令牌,但又希望一旦他们有了令牌,所有人都可以使用静态变量,而不需要携带非零大小的静态变量的引用,这可能很有用。

没有运行时依赖