Your first attempt:
pub static SOME_LEVELS: &'static Vec<&'static SomeLevel> = &[
SomeLevel { value: 0.0, priority: 1, color: "".to_string()},
];
fails because a Vec
is a completely different type to a static array in rust. A Vec
is a dynamically growable heap allocated Vector type, while an array is a fixed size array, typically allocated on the stack.
You can correct this by altering some_levels
to be an array (assuming that you don't actually need the facilities of a Vec
):
pub static SOME_LEVELS: &[SomeLevel; 1] = &[
SomeLevel { value: 0.0, priority: 1, color: "".to_string()},
];
This still does not compile though:
error[E0015]: cannot call non-const fn `<str as ToString>::to_string` in statics
--> src/lib.rs:18:60
|
18 | SomeLevel { value: 0.0, priority: 1, color: "".to_string()},
| ^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
The reason for this error is that functions used to initialize a static need to be const
, and to_string()
is not const
. It is possible to create an empty string using String::new()
, which is a const
function, but I am assuming that your real life lookup table would not contain only empty strings.
This leaves you with a couple of choices. If SomeLevel::color
does not really need to be a String - for example if it is actually only ever assigned to fixed string literals - then you can change it to be &'static str
:
#[derive(Debug)]
pub struct SomeLevel {
pub value: f64,
pub priority: u8,
pub color: &'static str
}
// ....
pub static SOME_LEVELS: &[SomeLevel; 1] = &[
SomeLevel { value: 0.0, priority: 1, color: ""},
];
Note that statics in rust are always immutable, so if this is the only use case of SomeLevel
then most likely &'static str
is what you want. If you really did need to have a String
, then you would have to use lazy initialization of your static table, like this:
use once_cell::sync::Lazy;
// ...
pub static SOME_LEVELS: Lazy<[SomeLevel; 1]> = Lazy::new(|| [
SomeLevel { value: 0.0, priority: 1, color: "".to_string() },
]);
Here we use once_cell::sync::Lazy
to lazily initialize SOME_LEVELS the first time it is referenced. It is initialized within a closure called by Lazy::new
, which also means that the intialization value must be returned by value rather than reference.
Note: Lazy
is also available in the standard library, under the name LazyCell
, however it is not stabilized yet. The once_cell
crate can be used in the meanwhile. lazy_static
is another crate that provides similar functionality.