Filling a static array from different modules in Rust?

867 Views Asked by At

In my Rust project, I need a globally hold, static array or vec that is initialized once where modules can register values or functions on. I thought, this would be possible using the lazy_static!-crate, but it doesn't seem so.

This is what I want to achieve:

  • Module a initializes an array/vec with some data.
  • Module b (or further modules) then extend this array/vec to further data.
  • All this should only be done once at program startup, and the array won't be modified during the program's execution. It is just a lookup-table, globally hold, but once created from several modules.

This is my first draft, which does not work playground link

mod a
{
    use lazy_static::lazy_static; // 1.4.0

    lazy_static!{
        #[derive(Debug)]
        pub static ref TEST: Vec<u32> = vec![1, 2, 3];
    }
}

mod b  // when module b is removed, it works. 
{
    use lazy_static::lazy_static; // 1.4.0
    use crate::a::TEST;

    lazy_static!{
        TEST.extend(vec![4, 5, 6]);
    }
}

use a::TEST;

fn main() {
    for i in 0..TEST.len() {
        println!("{}", TEST[i]);
    }
}

Can anybody help?

1

There are 1 best solutions below

3
On BEST ANSWER

A couple things to note:

  • as far as I know, lazy_static! is for declaring static variables, so mod b can't use the macro just to mutate other statics, like you are trying in your example
  • for statics to be mutable in Rust, you need to wrap them in a Mutex to follow Rust's whole thing of guaranteeing thread safety
  • modules are designed to collect things like structs, functions, traits, etc., so if you want them to 'do' something, you need to have it in a function call.

All that being said, I hope this snippet can help you out.

Rust Playground

mod a {
    use lazy_static::lazy_static; // 1.4.0
    use std::sync::Mutex;

    lazy_static!{
        #[derive(Debug)]
        pub static ref TEST: Mutex<Vec<u32>> = Mutex::new(vec![1, 2, 3]);
    }
}

mod b {
    use crate::a::TEST;
    
    pub fn append_to_test() {
        TEST.lock().unwrap().extend(vec![4, 5, 6]);
    }
}

use a::TEST;

fn main() {
    crate::b::append_to_test();
    
    println!("{:?}", TEST.lock().unwrap());
}