How to create a static array of strings?

ArraysStringStaticRust

Arrays Problem Overview


> Note This question contains syntax that predates Rust 1.0. The code is invalid, but the concepts are still relevant.

How do you create a global static array of strings in Rust?

For integers, this compiles:

static ONE:u8 = 1;
static TWO:u8 = 2;
static ONETWO:[&'static u8, ..2] = [&ONE, &TWO];

But I can't get something similar for strings to compile:

static STRHELLO:&'static str = "Hello";
static STRWORLD:&'static str = "World";
static ARR:[&'static str, ..2] = [STRHELLO,STRWORLD]; // Error: Cannot refer to the interior of another static

Arrays Solutions


Solution 1 - Arrays

This is a stable alternative for Rust 1.0 and every subsequent version:

const BROWSERS: &'static [&'static str] = &["firefox", "chrome"];

Solution 2 - Arrays

There are two related concepts and keywords in Rust: const and static:

<https://doc.rust-lang.org/reference/items/constant-items.html>

For most use cases, including this one, const is more appropriate, since mutation is not allowed, and the compiler may inline const items.

const STRHELLO:&'static str = "Hello";
const STRWORLD:&'static str = "World";
const ARR:[&'static str, ..2] = [STRHELLO,STRWORLD];

Note, there is some out-of-date documentation out there that doesn't mention the newer const, including Rust by Example.

Solution 3 - Arrays

Another way to do it nowadays is:

const A: &'static str = "Apples";
const B: &'static str = "Oranges";
const AB: [&'static str; 2] = [A, B]; // or ["Apples", "Oranges"]

Solution 4 - Arrays

Just used this to allocate a small POC level for a game in Rust

const LEVEL_0: &'static [&'static [i32]] = &[
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    &[1, 9, 0, 0, 0, 2, 0, 0, 3, 1],
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];

And loaded using the following function

pub fn load_stage(&mut self, ctx: &mut Context, level: usize) {
    let levels = vec![LEVEL_0];

    for (i, row) in levels[level].iter().enumerate() {
        for (j, col) in row.iter().enumerate() {
            if *col == 1 {
                self.board.add_block(
                    ctx,
                    Vector2::<f32>::new(j as f32, i as f32),
                    self.cell_size,
                );
            }

Solution 5 - Arrays

Nowadays You can write it without indirection through a pointer:

const ONETWO: [u8;2]   = [1, 2];
const ARRAY:  [&str;2] = ["Hello", "World"];

fn main() {
    println!("{} {}", ONETWO[0], ONETWO[1]);  // 1 2
    println!("{} {}", ARRAY[0], ARRAY[1]);  // Hello World
}


Thanks to static lifetime elision, you usually don’t have to explicitly use

'static like in:

const ARRAY: [&'static str;2] = ["Hello", "World"];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrew WagnerView Question on Stackoverflow
Solution 1 - ArraysQuartzView Answer on Stackoverflow
Solution 2 - ArraysAndrew WagnerView Answer on Stackoverflow
Solution 3 - ArraysAdrianView Answer on Stackoverflow
Solution 4 - ArraysEduardo PereiraView Answer on Stackoverflow
Solution 5 - ArraysKaplanView Answer on Stackoverflow