Reputation: 323
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
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
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
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