49

I am trying to initialize a Vec<String> with some settings that can be reused over my code.

I am using const left: Vec<String> = vec![... but this doesn't work:

error[E0308]: mismatched types
  --> names-generator.rs:2:27
   |
2  | const left: Vec<String> = vec![
   |                           ^ expected slice, found array of 93 elements
   |
   = note: expected type `Box<[std::string::String]>`
   = note:    found type `Box<[&str; 93]>`
   = note: this error originates in a macro outside of the current crate

What is the recommended way of doing something like this?

3
  • String literals are of type &'static str, not String. String is a string on heap. Commented Mar 13, 2017 at 12:53
  • 2
    They are not unrelated; in fact they are strongly related. The only way to make a Vec or a String is at runtime because they each require heap allocation. The only way to have a single instance of a runtime value like Vec or String is through the mechanism of somethign like InitOnce or lazy_static!. Commented Mar 15, 2017 at 12:37
  • 1
    the answer bellow works for me and I am not using any of those. Commented Mar 15, 2017 at 14:02

1 Answer 1

70

Do you want it to be mutable? Do the values have to be Strings? If the answer is "no" to both, you can use an array of string slices ([&str; N]) instead of a Vec<String>:

const LEFT: [&'static str; 3] = ["Hello", "World", "!"];
// or
const LEFT: &'static [&'static str] = &["Hello", "World", "!"];

consts are basically copied wherever they are used, so the second form may be preferable depending on the size of the array.

Sign up to request clarification or add additional context in comments.

6 Comments

The array is quite big. so probably I don't want it copied everywhere. Still trying to make sense of that signature though. Thanks
The first one is an array of 3 references to static strings, the second one is a reference to a static array of references to static strings. Static here means the lifetime = lifetime of the program, so effectively stuff that's stored in the DATA section of the executable. I see that the array has 93 elements: 93 64-bit pointers is way smaller than a CPU cache line so the first signature might actually be faster, definitely worth benchmarking.
@glebm Not true. A CPU cache line (on typical desktop and mobile CPUs) is 64 bytes. 93 64-bit pointers would occupy 744 bytes in total, or 12 cache lines.
@BrennanVincent is absolutely right. Also each slice is actually a pointer + length, so it's 16 bytes per slice.
@Mike: If the answer is "yes" then initialization at runtime is required, possibly using lazy_static or similar tools to ensure that initialization is performed exactly once.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.