使用带有矢量的地图

时间:2015-05-04 09:36:48

标签: rust

尽管向量最适合程序编程,但我想对它们使用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)。有没有其他方法来处理它?<​​/ p>

2 个答案:

答案 0 :(得分:58)

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()可能是它中最神奇的部分,并允许您将迭代器的所有元素收集到各种不同类型中,如implementors of FromIterator所示。例如,可以将T的迭代器收集到Vec<T>char的{​​{1}}可以收集到String(K, V)HashMap<K, V> {1}},等等。

这种使用迭代器的方式也意味着你甚至不需要创建其他语言或其他技术的中间向量;这样更有效,通常也很自然。

答案 1 :(得分:13)

正如by bluss所指出的,你也可以使用mutable迭代器来改变值,而不改变类型:

[r, c] = find(img);

img_cropped = img(min(r):max(r), min(c):max(c))
  

函数let mut nums = nums; for num in &mut nums { *num += 1 } println!("{:p} - {:?}", &nums, nums); 在Rust 1.3中已弃用,并且在Rust 1.4中不再存在。

Chris Morgan的回答是99%的最佳解决方案。但是,有一个名为Vec::map_in_place的专门函数。这样做的好处是不需要任何额外的内存分配,但它要求输入和输出类型具有相同的大小(thanks Levans)并且当前不稳定:

Vec::map_in_place

一个例子:

fn map_in_place<U, F>(self, f: F) -> Vec<U> 
    where F: FnMut(T) -> U