добавив одно и то же целое число к каждому элементу вектора в Rust - PullRequest
0 голосов
/ 11 октября 2019

В python, если у меня есть список и я хочу добавить 10 к каждому элементу, я бы сделал:

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

, что приведет к: [12,14,15,16,17].
Как это можно сделать в Rust? Является ли единственный способ сделать цикл for и пройти каждый элемент вектора?

1 Ответ

1 голос
/ 11 октября 2019

Способ Rust сделать это очень похож на Python: используйте итераторы! Грубый эквивалент понимания списка в Python: iter::map для получения новых элементов и iter::collect для сбора в новый вектор (или какой-либо другой вид коллекции).

Так, например, если barявляется Vec<i32> (или любым другим примитивным целочисленным типом), и вы хотите добавить 10 к каждому элементу, попробуйте

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

(детская площадка)

В качестве альтернативы,Вы можете изменить элементы на месте с помощью

bar.iter_mut().for_each(|x| *x += 10);

(детская площадка)

Это в основном похоже на цикл 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);
}

(детская площадка)

...