7个不稳定版本 (3个破坏性更新)

0.5.0 2023年6月8日
0.4.1 2023年1月12日
0.3.2 2022年11月23日
0.3.1 2022年9月16日
0.1.3 2022年9月8日

#2174 in Rust模式

Download history 118/week @ 2024-03-24 166/week @ 2024-03-31 170/week @ 2024-04-07 153/week @ 2024-04-14 145/week @ 2024-04-21 124/week @ 2024-04-28 135/week @ 2024-05-05 131/week @ 2024-05-12 135/week @ 2024-05-19 72/week @ 2024-05-26 136/week @ 2024-06-02 243/week @ 2024-06-09 244/week @ 2024-06-16 156/week @ 2024-06-23 186/week @ 2024-06-30 164/week @ 2024-07-07

每月754次下载
2个crate中使用(通过easyfft

MIT/Apache

21KB
184

generic_singleton

Rust不对其静态泛型项进行单态化。这意味着您不能在泛型函数中使用静态泛型项。您将获得以下错误

error[E0401]: can't use generic parameters from outer function

当您想要编写依赖于泛型参数的单例模式时,这非常令人沮丧。这个crate允许以最小的运行时开销来实现这种模式。

generic_singleton在幕后使用anymap存储每个泛型类型的映射。第一次调用get_or_init宏时,我们将初始化单例。随后的get_or_init调用将从映射中检索单例。

示例

use std::{ops::AddAssign, sync::RwLock};

use num_traits::{One, Zero};

fn generic_call_counter<T: Zero + One + Copy + AddAssign + Send + Sync + 'static>() -> T {
    let mut count = generic_singleton::get_or_init!(|| RwLock::new(T::zero())).write().unwrap();
    *count += T::one();
    *count
}

fn main() {
    // Works with usize
    assert_eq!(generic_call_counter::<usize>(), 1);
    assert_eq!(generic_call_counter::<usize>(), 2);
    assert_eq!(generic_call_counter::<usize>(), 3);

    // Works with i32
    assert_eq!(generic_call_counter::<i32>(), 1);
    assert_eq!(generic_call_counter::<i32>(), 2);
    assert_eq!(generic_call_counter::<i32>(), 3);

    // Works with f32
    assert_eq!(generic_call_counter::<f32>(), 1.0);
    assert_eq!(generic_call_counter::<f32>(), 2.0);
    assert_eq!(generic_call_counter::<f32>(), 3.0);
}

线程局部变体

上述示例的缺点是需要一个RwLock来确保围绕内部AnyMap的同步。在单线程情况下,我们可以移除此锁,并使用get_or_init_thread_local!宏直接提供可变引用。这以牺牲易用性为代价,需要您以闭包的形式表达您的逻辑,而不是简单地返回一个引用。

依赖关系

~0.4–6MB
~12K SLoC