Convertir Vec <Vec <u8>> en & [& [u8]] [dupliquer]

Nov 08 2020

J'ai une fonction qui prend un certain nombre de chaînes d'octets: &[&[u8]]mais je veux l'appeler avec un argument de type Vec<Vec<u8>>. Appel de la fonction comme ceci:

let foo: Vec<Vec<u8>> = Vec::new();
bar(&foo[..]);

convertit fooen une tranche mais pas les valeurs qu'il contient. Existe-t-il un moyen de faire cette conversion facilement et efficacement? Ou puis-je changer le type de l'argument de la fonction pour éviter des cas comme celui-ci?

Réponses

2 L.F. Nov 08 2020 at 19:35

Une façon de gérer ce cas sans allouer de supplément Vecconsiste à utiliser AsRef<[u8]>:

fn bar<S: AsRef<[u8]>>(args: &[S]) {
    // ...
}

Dans la fonction, vous pouvez utiliser .as_ref()pour convertir chacun des arguments en un fichier &[u8].

( aire de jeux )

2 Locke Nov 08 2020 at 16:11

Du point de vue de la mémoire, cela n'a pas beaucoup de sens. Pour créer une tranche, les données découpées doivent d'abord exister en mémoire. Cependant, pour prendre une tranche de &[u8], vous devez d'abord avoir une structure de données comme Vec<&[u8]>pour prendre la tranche.

En d'autres termes, pour ce faire, vous devez d'abord allouer de l'espace pour Vec<&[u8]>ou [&[u8]; N]et le remplir de tranches. Cela va quelque peu à l'encontre de l'objectif de l'utilisation des tranches puisque les tranches sont destinées à la mémoire de référence existante en place. Pensez à utiliser &[Vec<u8>]pour votre fonction à la place.

Si la présence de tranches dans la deuxième couche est importante ou si vous ne parvenez pas à modifier la fonction, vous pouvez effectuer les opérations suivantes pour convertir Vec<Vec<u8>>en &[&[u8]]:

let foo: Vec<Vec<u8>> = Vec::new();

// Allocate Vec of references to slices
let tmp: Vec<&[u8]> = foo.iter().map(|x| &x[..]).collect();

// Take slice of temporary Vec
bar(&tmp[..]);