Sure, you can. But given that this is a forum where beginners seek help, people are going to jump in when someone suggests hazardous or unsound code is to point out that the code is hazardous or unsound, and also suggest to beginners that it is probably not anything they want to dive into without more experience with the language. Aside from guiding them to write idiomatic Rust, it would be irresponsible to do otherwise.
Sorry the topic got off track.
When you say "constant array", I take that to mean that the contents are all known at compile time and will not change, right? If so, you want what @kpreid and @cole-miller suggested:
static COMPONENTS: &[&str] = &["str1", "str2"];
It will mostly act like an immutable Vec
. Most of the non-size-changing operations you're used to on a Vec
are really operations on slices (like [&str]
), because a Vec
dereferences to a slice.
If you do need to build it once at runtime, you can use a OnceCell
.
static COMPONENTS: Lazy<Vec<String>> = Lazy::new(|| {
let mut v = Vec::new();
let command = std::env::args_os()
.map(|arg| arg.to_string_lossy().into_owned())
.next()
.unwrap_or_else(|| "This Program".to_string());
v.push(command);
v
});
Playground.
If you need to modify during runtime after you build it, you'll need some sort of synchronization as well, such as a Mutex
.
static COMPONENTS: Lazy<Mutex<Vec<String>>> = Lazy::new(|| {
let mut v = Vec::new();
let command = std::env::args_os()
.map(|arg| arg.to_string_lossy().into_owned())
.next()
.unwrap_or_else(|| "This Program".to_string());
v.push(command);
Mutex::new(v)
});
Playground.
The other suggestions like lazy_static
are variations on this approach.
Don't use static mut
. You'll have to use unsafe
to access it, and it's such a foot gun that experts get it wrong and it will likely be deprecated. It's the difficulty in avoiding undefined behavior that's the problem, not needing a global variable per se; in fact, OnceCell
or something very much like it will likely become part of the standard library.