user3161500
user3161500

Reputation: 323

Initializing an array of strings in Rust

I want to create a mutable array of a fixed size. The elements are initialized later in the program. How do I initialize the array?

I tried doing this:

let mut array: [String; 126] = [String::new(); 126];

and it gives me the error:

the trait bound 'std::string::String: std::marker::Copy' is not satisfied
the trait 'std::marker::Copy' is not implemented for 'std::string::String'

how do I initialize the array with new strings?

Upvotes: 21

Views: 34644

Answers (3)

jilles
jilles

Reputation: 11252

There are ways that work for types without const ways to construct them, for example:

let mut a = [(); 126].map(|_| String::new());

The other answer with const EMPTY_STRING: String = String::new() is probably better for this particular case, as the documentation of the array::map method warns that this might be inefficient and consume a lot of stack space.

In nightly (as of Rust 1.57), there is also an even nicer function std::array::from_fn().

Upvotes: 6

Dmitry Mottl
Dmitry Mottl

Reputation: 882

You can use (the result of) a const function, for example String::new(), to initialize an array:

const EMPTY_STRING: String = String::new();
let mut array: [String; 126] = [EMPTY_STRING; 126];

Upvotes: 4

E_net4
E_net4

Reputation: 30062

At the moment, initialization of arrays is still a bit quirky. In particular, having Default would have been useful here, but it's only implemented for arrays up to 32:

let array: [String; 32] = Default::default();

Any number over that will fail to compile because, while Rust 1.47 now implements some traits over a generic size for array types, Default is yet not one of them. These 32 implementations of Default were "sort-of" added manually.

We can overcome that with alternative container types, such as Vec. The vec! macro will let you clone a string as many times as you wish to fill in the new vector:

let mut array: Vec<String> = vec![String::new(); 126];

But of course, depending on your use case, you might also consider going lazy and only collecting the final outcomes using the Iterator API.

Upvotes: 29

Related Questions