美文网首页
Rust全局变量之once_cell

Rust全局变量之once_cell

作者: 黑天鹅学院 | 来源:发表于2021-07-26 16:29 被阅读0次

    在前文中我们分析了使用lazy_static来构造全局变量,典型用法如下:

    #[macro_use]
    extern crate lazy_static;
    
    use std::collections::HashMap;
    
    lazy_static! {
        static ref VEC:Vec<u8> = vec![0x19u8, 0x21u8];
        static ref MAP: HashMap<u32, String> = {
            let mut map = HashMap::new();
            map.insert(2021, "year".to_owned());
            map
        };
        static ref PAGE:u32 = init_val(2018);
    }
    
    fn init_val(i: u32) -> u32 {
        i * 2
    }
    
    fn main() {
        println!("{:?}", *PAGE);
        println!("{:?}", *VEC);
        println!("{:?}", *MAP);
    }
    

    once_cell 提供了 unsync::OnceCell 和 sync::OnceCell 这两种接口,前者用于单线程,后者用于多线程,可用来存储堆上的信息,并且具有最多只能赋值一次的特性。

    提供的API如下:
    fn set(&self, value: T) -> Result<(), T> { ... } => 安全的设置全局变量
    fn get(&self) -> Option<&T> { ... } => 获取已经设置的全局变量
    get_or_init(Fn) => 获取全局变量,为空则初始化
    Lazy::new(Fn) => 延迟创建全局变量

    典型用法如下:

    use std::{sync::Mutex, collections::HashMap};
    use once_cell::sync::Lazy;
    use once_cell::sync::OnceCell;
    
    static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
        let mut m = HashMap::new();
        m.insert(13, "chain".to_string());
        m.insert(74, "queue".to_string());
        Mutex::new(m)
    });
    
    fn global_data() -> &'static Mutex<HashMap<i32, String>> {
        static INSTANCE: OnceCell<Mutex<HashMap<i32, String>>> = OnceCell::new();
        INSTANCE.get_or_init(|| {
            let mut m = HashMap::new();
            m.insert(13, "sky".to_string());
            m.insert(74, "walker".to_string());
            Mutex::new(m)
        })
    }
    

    相比而言,once_cell没有采用宏的方式实现,代码看起来更加干净易懂。

    相关文章

      网友评论

          本文标题:Rust全局变量之once_cell

          本文链接:https://www.haomeiwen.com/subject/sceiultx.html