如何在 Rust 中将相同的整数添加到向量的每个元素?

How do I add the same integer to each element of a vector in Rust?

在 Python 中,如果我有一个列表并想向每个元素添加 10,我会这样做:

bar = [2,4,5,6,7]
bar = [x + 10 for x in bar]

导致:[12,14,15,16,17]。这在 Rust 中如何实现?执行 for 循环并遍历每个向量元素的唯一方法是什么?

Rust 的实现方式与 Python 非常相似:使用迭代器! Python 的列表理解的粗略等效是 iter::map 获取新元素,iter::collect 收集到新向量(或其他某种集合)中。

因此,例如,如果 bar 是一个 Vec<i32>(或任何其他原始整数类型)并且您想为每个元素加 10,请尝试

bar = bar.into_iter().map(|x| x + 10).collect();

(playground)

或者,您可以使用

就地改变元素
bar.iter_mut().for_each(|x| *x += 10);

(playground)

这基本上类似于 for 循环,但更加简洁。这通常比第一种方法更有效,因为您不需要分配新的向量(足够聪明的编译器可能能够避免这种情况)。唯一的缺点是这个版本不太灵活。输出仍然需要是一个向量;你不能切换到哈希集或者你有什么。您也无法保留旧矢量的副本。请参阅下面的一些可能的示例。

fn main() {
    let mut bar = vec![2, 4, 5, 6, 7];
    // Overwrite the old vector
    bar = bar.into_iter().map(|x| x + 10).collect();
    println!("new bar: {:?}", bar);

    let bar = vec![2, 4, 5, 6, 7];
    // Make a completely new vector
    // Note that this works only because i32 implements the Copy trait,
    // so we can make copies of the elements of bar without any problems
    // In more general situations, we may need to clone each element
    let foo: Vec<_> = bar.iter().map(|&x| x + 10).collect();
    println!("old bar: {:?} (it's still around)", bar);
    println!("new foo: {:?}", foo);

    use std::collections::HashSet;
    let bar = vec![2, 4, 5, 6, 7];
    // transform the data and collect it into a HashSet
    // instead of a vector
    let bar: HashSet<_> = bar.into_iter().map(|x| x + 10).collect();
    println!("new bar: {:?} (note that now bar is unordered)", bar);

    let mut bar = vec![2, 4, 5, 6, 7];
    // Overwrite the old vector in place
    bar.iter_mut().for_each(|x| *x += 10);
    println!("new bar: {:?}", bar);
}

(playground)

这是基本代码,它说明了如何按照问题默认假定的方式进行操作。它可能对像我这样的 Rust 初学者有用:

fn increment_mut(p: &mut Vec<i32>, to_add: i32){
    for i in 0..p.len() {
        p[i] += to_add;
    }
}

fn main() {
    let mut p = vec![2, 4, 5, 6, 7];
    increment_mut(&mut p, 10);

    // Print the complete vector in Debug.
    println!("{:?}", p)
}
$ cargo run
[12, 14, 15, 16, 17]

使用iter_mut

fn increment_mut2(p: &mut Vec<i32>, to_add: i32) {
    for x in p.iter_mut() {
        *x += to_add;
    }
}

fn main() {
    let mut p = vec![2, 4, 5, 6, 7];
    increment_mut2(&mut p, 10);

    // Print the complete vector in Debug.
    println!("{:?}", p)
}
$ cargo run
[12, 14, 15, 16, 17]