【问题标题】:Rust: apply the function to each element of vectorRust:将函数应用于向量的每个元素
【发布时间】:2022-11-02 23:31:26
【问题描述】:

给定以下功能:

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
}

我怎样才能让它工作?

【问题讨论】:

  • 您真的打算将函数index - 1 应用于每个元素吗?
  • 如果您只使用 x 重新计算的最后一个值,我不明白迭代超过 1..index 的目标。
  • 是的,我必须将函数 i 次应用于 i-th 元素
  • [x, x, x] => [x, f(x), f(f(x))]
  • @Ali:在这种情况下,我相信你有一个错误。 1..index 迭代 index - 1 次,而 index 是基于 0 的,因此您在索引 0 和 1 处有 0 次迭代,在索引 2 处有 1 次迭代,在索引 3 处有 2 次迭代,等等...您应该使用 @987654327 @ 反而。

标签: rust


【解决方案1】:

Rust 中有 3 种类型的变量:

  • 值。
  • 共享参考。
  • 可变引用。

反过来,这映射到 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);
            }
        });
}

【讨论】:

    【解决方案2】:

    此示例不起作用,因为.iter() 不会生成拥有变量的迭代器,而是对vs 的元素的引用。您可以通过将其转换为 into_iter() 来修补您的代码:

    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()
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-28
      • 2013-10-13
      • 1970-01-01
      • 2015-12-28
      • 2012-12-21
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多