3
votes

Quel est l'équivalent Rust de l'opérateur de propagation de JavaScript pour les tableaux?

En JavaScript, il existe un opérateur appelé opérateur de diffusion qui vous permet de combiner des tableaux de manière très concise.

let x = [3, 4];
let y = [5, ...x]; // y is [5, 3, 4]

Y a-t-il un moyen de faire quelque chose comme ça dans Rust?


0 commentaires

3 Réponses :


4
votes

Les tableaux de Rust ont une longueur fixe , il n'y a donc pas façon de simplement les combiner ensemble; la manière habituelle d’obtenir ce résultat serait d’avoir un vecteur mutable et de étendez-le avec une tranche:

fn main() {
    let x = [3, 4];
    let mut y = vec![5];
    y.extend_from_slice(&x);

    println!("{:?}", y); // [5, 3, 4]
}


7 commentaires

Il n'y a donc pas de moyen concis pour: ajouter x ou & x [..] au vecteur dans la même ligne que vec! [5] , puis faire quelque chose avec le résultat avant d'affecter à y ?


Les références @laptou seules ne peuvent pointer que vers une valeur existante (pour les tranches, ce serait une section contiguë de valeurs [T] ), donc aucune nouvelle valeur ne peut être ajoutée via une tranche. La manipulation dynamique des séquences est généralement effectuée avec des vecteurs, afin qu'ils puissent posséder cette mémoire.


@laptou autant que je me souvienne, il y avait une fois une suggestion pour implémenter Add entre Vec et & [T] , tel quel déjà possible avec String et & [str] , mais il a été rejeté.


@ E_net4 Je comprends, mais comme ce sont des valeurs primitives qui implémentent Copy (dans mon cas d'utilisation spécifique, j'essaye de concaténer un Vec avec [ u8; 2] en une seule ligne) J'espérais qu'il pourrait y avoir un raccourci.


@laptou oui, je l'ai trouvé: Implémenter Add for Vec .


@laptou En effet, ajouter des valeurs à un vecteur existant est possible, bien qu'il n'y ait actuellement aucune syntaxe standard pour le faire sur une seule ligne. Extend est un trait approprié à utiliser ici une fois que vous avez déjà construit un vecteur quelque part.


Cela dit, les tableaux Rust ayant une longueur fixe ne seraient pas un obstacle à la propagation des tableaux dans le cadre de la syntaxe du langage, tant que les entrées et les sorties étaient également des tableaux. Je ne serais pas surpris si quelqu'un proposait déjà une telle syntaxe dans une RFC ou construisait simplement une macro pour obtenir un effet similaire.



-3
votes

Non, mais peut-être que vous pouvez essayer de créer une macro, similaire à vec!


0 commentaires

3
votes

Si vous avez juste besoin de y pour être itérable, vous pouvez faire:

let y: Vec<_> = [5].iter().chain(&x).map(|&x|x).collect();

Si vous avez besoin qu'il soit indexable, vous voudrez le collecter en un vecteur.

let x = [3,4];
let y = [5].iter().chain(&x);


5 commentaires

Cela marche. Y a-t-il des implications significatives sur les performances en procédant de cette manière?


@laptou: J'en doute. Mais vous pouvez comparer l'assemblage de sortie ici: play.rust-lang. org /…


@BenjaminLindley, ils le seront sans aucun doute puisque le tableau est créé sur la pile, et Vec est une structure allouée au tas.


@AlexZhukovskiy: À quoi le comparez-vous? J'ai supposé que nous le comparions à la solution Ijedrz, qui utilise également un vecteur. Avez-vous une méthode qui n'en a pas?


Je comparais avec la mise en œuvre manuelle. Il pourrait être écrit comme méthode, puis les génériques const sont stabilisés.