How to declare a static array of vectors?

Viewed 962

How would one go about declaring a static/constant array of variable-sized arrays (vectors) in Rust? In C++ you could do something like this:

static const std::vector<std::string> MY_STRINGS[] = {
    { "hi" },
    { "hello", "world" },
    { "salutations", "watery", "globe" }
};

and things would work as you expect (the array is constructed during app launch afaik). What's the equivalent code in Rust? Seems like the compiler is trying its very best to prevent me from doing this.

3 Answers

Currently you cannot have 'const' items with destructors, so Vec is not allowed.

If you know the size of the "vec" at compile time, you can use an array:

const MY_STRS: [&'static str; 3] = [
  "first",
  "second",
  "third"
];

Otherwise, I'd suggest looking at the lazy_static crate: https://crates.io/crates/lazy_static

This lets you write something like the following:

lazy_static! {
  static ref MY_STRS: Vec<String> = {
    let mut strings = vec![];
    strings.push("hello".to_string());
    strings
  }
}

This behaves as the name suggests; it is lazily initialized when first accessed.

I'd recommend reading the docs for this crate to get an understanding of the thread-safety implications

If you are on nightly, you can use LazyLock. Like this:

#![feature(once_cell)]   // 1.65.0-nightly

use std::sync::LazyLock;

const MY_STRINGS: LazyLock<[Vec<&str>; 3]> =
    LazyLock::new(|| [
        vec!["hi"], 
        vec!["hello", "world"],
        vec!["salutations", "watery", "globe"]
    ]);

fn main() {
    println!("{}, {}", MY_STRINGS[1][0], MY_STRINGS[2][2]);
}

LazyLock more or less does what the crates once_cell and lazy_sync do. Those two crates are very common, so there's a good chance they might already by in your Cargo.lock dependency tree. But if you prefer to be a bit more "adventurous" and go with LazyLock, be prepered that it (as everything in nightly) might be a subject to change before it gets to stable.

(Note: Up until recently std::sync::LazyLock used to be named std::lazy::SyncLazy but was recently renamed.)

Related