Summary
Add back the functionality of Vec::from_elem by improving the vec![x; n] sugar to work with Clone x and runtime n.
Motivation
High demand, mostly. There are currently a few ways to achieve the behaviour of Vec::from_elem(elem, n):
// #1
let vec = Vec::new();
for i in range(0, n) {
vec.push(elem.clone())
}
// #2
let vec = vec![elem; n]
// #3
let vec = Vec::new();
vec.resize(elem, n);
// #4
let vec: Vec<_> = (0..n).map(|_| elem.clone()).collect()
// #5
let vec: Vec<_> = iter::repeat(elem).take(n).collect();
None of these quite match the convenience, power, and performance of:
let vec = Vec::from_elem(elem, n)
#1is verbose and slow, because eachpushrequires a capacity check.#2only works for a Copyelemand constn.#3needs a temporary, but should be otherwise identical performance-wise.#4and#5are considered verbose and noisy. They also need to clone one more time than other methods strictly need to.
However the issues for #2 are entirely artificial. It's simply a side-effect of
forwarding the impl to the identical array syntax. We can just make the code in the
vec! macro better. This naturally extends the compile-timey [x; n] array sugar
to the more runtimey semantics of Vec, without introducing "another way to do it".
vec![100; 10] is also slightly less ambiguous than from_elem(100, 10),
because the [T; n] syntax is part of the language that developers should be
familiar with, while from_elem is just a function with arbitrary argument order.
vec![x; n] is also known to be 47% more sick-rad than from_elem, which was
of course deprecated to due its lack of sick-radness.
Detailed design
Upgrade the current vec! macro to have the following definition:
(note: only the [x; n] branch is changed)
Which allows all of the following to work:
fn main() {
println!("{:?}", vec![1; 10]);
println!("{:?}", vec![Box::new(1); 10]);
let n = 10;
println!("{:?}", vec![1; n]);
}
Drawbacks
Less discoverable than from_elem. All the problems that macros have relative to static methods.
Alternatives
Just un-delete from_elem as it was.
Unresolved questions
No.