Rust:将函数应用于矢量的每个元素

pqwbnv8z  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(139)

给定以下函数:

fn some_function<K, F: Fn(K) -> K>(f: F, vs: Vec<K>) -> Vec<K> {
    let mut index = 0;
    let new_vec = vs.iter().map(|x| {
        index += 1;
        for _ in 1 .. index {
            x = f(x); // <- error here: mismatched types expected reference `&K` found type parameter `K`
        }
        *x
    }).collect();
    new_vec
}

我怎么才能让它工作呢?

fnx2tebb

fnx2tebb1#

Rust中有3种类型的变量:

  • 价值观。
  • 共享参考资料。
  • 可变引用。

这又Map到3个不同的迭代函数:

  • .into_iter()将返回一个值的迭代器。
  • .iter()将返回共享引用上的迭代器。
  • .iter_mut()将返回可变引用上的迭代器。

您只是没有选择正确的函数,而应该使用into_iter

fn some_function<K, F: Fn(K) -> K>(f: F, vs: Vec<K>) -> Vec<K> {
    vs
        .into_iter()
        .enumerate()
        .map(|(index, mut x)| {
            for _ in 0..index {
                x = f(x);
            }
            x
        }).collect()
}

此外:

  • enumerate将允许您在迭代时获得每个元素的索引,这样您就不必自己维护索引。
  • 要迭代i项,您需要0..i,而不是1..i

然而,为了提高性能,如果可能的话,最好 * 就地 * 修改元素。这允许重用缓冲区,包括向量自己的缓冲区。结果将是:

fn some_function<K, F: Fn(&mut K)>(f: F, vs: &mut Vec<K>) {
    vs
        .iter_mut()
        .enumerate()
        .for_each(|(index, x)| {
            for _ in 0..index {
                f(x);
            }
        });
}
osh3o9ms

osh3o9ms2#

这个例子不起作用,因为.iter()不会产生一个所属变量的迭代器,而是对vs元素的引用。

fn some_function<K>(f: impl Fn(K) -> K, vs: Vec<K>) -> Vec<K> {
    let mut index = 0;
    vs.into_iter()
    .map(|mut x| {
        index += 1;
        for _ in 1..index { x = f(x); }
        x
    })
    .collect()
}

但您不需要跟踪index

fn some_function<K>(f: impl Fn(K) -> K, vs: Vec<K>) -> Vec<K> {
    vs
    .into_iter()
    .enumerate()
    .map(|(i, mut x)| {
        for _ in 0..i { x = f(x); }
        x
    })
   .collect()
}

相关问题