42

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?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
simao
  • 14,491
  • 9
  • 55
  • 66
  • String literals are of type `&'static str`, not `String`. `String` is a string on heap. – glebm Mar 13 '17 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!`. – Shepmaster Mar 15 '17 at 12:37
  • 1
    the answer bellow works for me and I am not using any of those. – simao Mar 15 '17 at 14:02

1 Answers1

60

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.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
glebm
  • 20,282
  • 8
  • 51
  • 67
  • The array is quite big. so probably I don't want it copied everywhere. Still trying to make sense of that signature though. Thanks – simao Mar 13 '17 at 13:46
  • 5
    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 Mar 13 '17 at 14:00
  • 2
    @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. – Brennan Vincent Nov 07 '19 at 09:37
  • 1
    @BrennanVincent is absolutely right. Also each slice is actually a pointer + length, so it's 16 bytes per slice. – glebm May 08 '20 at 19:38
  • And if the answer is "yes" to either... we do... what? – Mike 'Pomax' Kamermans Aug 06 '23 at 18:49
  • @Mike: If the answer is "yes" then initialization at runtime is required, possibly using [lazy_static](https://crates.io/crates/lazy_static) or similar tools to ensure that initialization is performed exactly once. – blerontin Aug 22 '23 at 08:50