将地图与矢量一起使用
Using map with Vectors
尽管向量最适合过程编程,但我想对它们使用 map
函数。以下代码段有效:
fn map<A, B>(u: &Vec<A>, f: &Fn(&A) -> B) -> Vec<B> {
let mut res: Vec<B> = Vec::with_capacity(u.len());
for x in u.iter() {
res.push(f(x));
}
res
}
fn f(x: &i32) -> i32 {
*x + 1
}
fn main() {
let u = vec![1, 2, 3];
let v = map(&u, &f);
println!("{} {} {}", v[0], v[1], v[2]);
}
为什么标准库中没有这样的函数? (也在 std::collections::LinkedList
中)。有没有其他方法可以解决?
Rust 喜欢比这更通用;映射是在迭代器上完成的,而不是仅仅在向量或切片上完成的。
几个演示:
let u = vec![1, 2, 3];
let v: Vec<_> = u.iter().map(f).collect();
let u = vec![1, 2, 3];
let v = u.iter().map(|&x| x + 1).collect::<Vec<_>>();
.collect()
is probably the most magic part of it, and allows you to collect all the elements of the iterator into a large variety of different types, as shown by the implementors of FromIterator
。例如,T
的迭代器可以收集到 Vec<T>
,char
的迭代器可以收集到 String
,(K, V)
对的迭代器可以收集到 HashMap<K, V>
,等等。
这种使用迭代器的方式还意味着您通常甚至不需要在其他语言或其他技术中创建中间向量;这样效率更高,通常也很自然。
正如 所指出的,您还可以使用可变迭代器在不更改类型的情况下就地改变值:
let mut nums = nums;
for num in &mut nums { *num += 1 }
println!("{:p} - {:?}", &nums, nums);
The function Vec::map_in_place
was deprecated in Rust 1.3 and is no longer present in Rust 1.4.
Chris Morgan 的回答在 99% 的情况下都是最佳解决方案。但是,有一个名为 Vec::map_in_place
. This has the benefit of not requiring any additional memory allocations, but it requires that the input and output type are the same size () 的专门函数,目前不稳定:
fn map_in_place<U, F>(self, f: F) -> Vec<U>
where F: FnMut(T) -> U
一个例子:
#![feature(collections)]
fn main() {
let nums = vec![1,2,3];
println!("{:p} - {:?}", &nums, nums);
let nums = nums.map_in_place(|v| v + 1);
println!("{:p} - {:?}", &nums, nums);
}
尽管向量最适合过程编程,但我想对它们使用 map
函数。以下代码段有效:
fn map<A, B>(u: &Vec<A>, f: &Fn(&A) -> B) -> Vec<B> {
let mut res: Vec<B> = Vec::with_capacity(u.len());
for x in u.iter() {
res.push(f(x));
}
res
}
fn f(x: &i32) -> i32 {
*x + 1
}
fn main() {
let u = vec![1, 2, 3];
let v = map(&u, &f);
println!("{} {} {}", v[0], v[1], v[2]);
}
为什么标准库中没有这样的函数? (也在 std::collections::LinkedList
中)。有没有其他方法可以解决?
Rust 喜欢比这更通用;映射是在迭代器上完成的,而不是仅仅在向量或切片上完成的。
几个演示:
let u = vec![1, 2, 3];
let v: Vec<_> = u.iter().map(f).collect();
let u = vec![1, 2, 3];
let v = u.iter().map(|&x| x + 1).collect::<Vec<_>>();
.collect()
is probably the most magic part of it, and allows you to collect all the elements of the iterator into a large variety of different types, as shown by the implementors of FromIterator
。例如,T
的迭代器可以收集到 Vec<T>
,char
的迭代器可以收集到 String
,(K, V)
对的迭代器可以收集到 HashMap<K, V>
,等等。
这种使用迭代器的方式还意味着您通常甚至不需要在其他语言或其他技术中创建中间向量;这样效率更高,通常也很自然。
正如
let mut nums = nums;
for num in &mut nums { *num += 1 }
println!("{:p} - {:?}", &nums, nums);
The function
Vec::map_in_place
was deprecated in Rust 1.3 and is no longer present in Rust 1.4.
Chris Morgan 的回答在 99% 的情况下都是最佳解决方案。但是,有一个名为 Vec::map_in_place
. This has the benefit of not requiring any additional memory allocations, but it requires that the input and output type are the same size (
fn map_in_place<U, F>(self, f: F) -> Vec<U>
where F: FnMut(T) -> U
一个例子:
#![feature(collections)]
fn main() {
let nums = vec![1,2,3];
println!("{:p} - {:?}", &nums, nums);
let nums = nums.map_in_place(|v| v + 1);
println!("{:p} - {:?}", &nums, nums);
}