问题
Hopping between languages can be painful. Idioms of one language "feel good" and one starts to look for the same idioms in other languages.
In F#, there is a way to init an array with the help of a generator function. Array.init n generator. Now, that I hopped to Rust for a little while, I wonder if there is a similar facility in place or if I have to create myself such a facility.
Studying Rust standard library documentation about vectors, I could not find anything similar to what I am looking for.
// Looking for something similar to:
Vec<T>::init(n : usize, generator : F) -> Vec<T>
where F: Fn(usize) -> T {
// ...
}
Maybe it works differently in Rust, by means of iterators. But I must admit, that Rust iterators (and their myriads of flavors) are still a tad foggy to my simple mind.
回答1:
You can use a range withing a map and then collect the results.
Like in the example for F# docs:
let my_vector : Vec<i32> = (1..11).map(|x| x*x).collect();
Check this live example
回答2:
Though @Netwave provides the answer, I'd point to a solution which uses it and provides both more reusability and readability.
Define a generic function, playground:
fn initialize<T>(count: usize, f: fn(usize) -> T) -> Vec<T> { (0..count).map(f).collect() } fn main() { let my_vector = initialize(10, |i| i as i32); for e in my_vector { println!("{}", e); } }Define a trait, implement it for whatever you want and use it, playground:
trait Initializer<T> { fn initialize(count: usize, f: fn(usize) -> T) -> Vec<T> { (0..count).map(f).collect() } } impl<T> Initializer<T> for Vec<T> {} fn main() { let my_vector = Vec::initialize(10, |i| i as i32); for e in my_vector { println!("{}", e); } }or more general way:
trait Initializer<T, U> { fn initialize(count: usize, f: fn(usize) -> U) -> T; } impl<T: std::iter::FromIterator<U>, U> Initializer<T, U> for T { fn initialize(count: usize, f: fn(usize) -> U) -> T { (0..count).map(f).collect::<T>() } } fn main() { let my_vector = Vec::initialize(10, |i| i as i32); for e in my_vector { println!("{}", e); } }Write a macro, playground:
macro_rules! vec_init { ($count: expr, $f: expr) => { (0..$count).map($f).collect() } } fn main() { let my_vector: Vec<i32> = vec_init!(10, |i| i as i32); }
The base still the same is in the @Netwave's answer. You've asked that you want something like:
// Looking for something similar to:
Vec<T>::init(n : usize, generator : F) -> Vec<T>
where F: Fn(usize) -> T {
// ...
}
And there is exactly this code in the second item.
回答3:
Pretty late to this party, but: resize_with
来源:https://stackoverflow.com/questions/48021408/how-to-init-a-rust-vector-with-a-generator-function