web-dev-qa-db-fra.com

Meilleure façon de concaténer des vecteurs dans Rust

Est-il même possible de concaténer des vecteurs dans Rust? Si oui, existe-t-il une manière élégante de le faire? J'ai quelque chose comme ça:

let mut a = vec![1, 2, 3];
let b = vec![4, 5, 6];

for val in &b {
    a.Push(val);
}

Est-ce que quelqu'un sait d'une meilleure façon?

35
Joe Thomas

La structure std::vec::Vec A la méthode append() :

fn append(&mut self, other: &mut Vec<T>)

Déplace tous les éléments de other dans Self, laissant other vide.

À partir de votre exemple, le code suivant concaténera deux vecteurs par en mutant a et b:

fn main() {
    let mut a = vec![1, 2, 3];
    let mut b = vec![4, 5, 6];

    a.append(&mut b);

    assert_eq!(a, [1, 2, 3, 4, 5, 6]);
    assert_eq!(b, []);
}

Alternativement, vous pouvez utiliser Extend::extend() pour ajouter tous les éléments de quelque chose qui peut être transformé en itérateur (comme Vec) à un vecteur donné:

let mut a = vec![1, 2, 3];
let b = vec![4, 5, 6];

a.extend(b);
assert_eq!(a, [1, 2, 3, 4, 5, 6]);
// b is moved and can't be used anymore

Notez que le vecteur b est déplacé au lieu d’être vidé. Si vos vecteurs contiennent des éléments qui implémentent Copy , vous pouvez passer une référence immuable à un vecteur à extend() à la place afin d'éviter le déplacement. Dans ce cas, le vecteur b n'est pas modifié:

let mut a = vec![1, 2, 3];
let b = vec![4, 5, 6];

a.extend(&b);
assert_eq!(a, [1, 2, 3, 4, 5, 6]);
assert_eq!(b, [4, 5, 6]);
49
Lud

Je ne peux pas le faire en une seule ligne. Damian Dziaduch

Il est possible de le faire sur une ligne en utilisant chain() :

let c: Vec<i32> = a.into_iter().chain(b.into_iter()).collect(); // Consumed
let c: Vec<&i32> = a.iter().chain(b.iter()).collect(); // Referenced
let c: Vec<i32> = a.iter().cloned().chain(b.iter().cloned()).collect(); // Cloned
let c: Vec<i32> = a.iter().copied().chain(b.iter().copied()).collect(); // Copied

Il y a des manières infinies.

2
Stargateur