Converti Vec <Vec <u8>> in & [& [u8]] [duplicato]

Nov 08 2020

Ho una funzione che accetta un certo numero di stringhe di byte: &[&[u8]]ma voglio chiamarla con un argomento di tipo Vec<Vec<u8>>. Chiamando la funzione in questo modo:

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

converte fooin una fetta ma non i valori che contiene. C'è un modo per eseguire questa conversione in modo semplice ed efficiente? Oppure posso cambiare il tipo di argomento della funzione per evitare casi come questo?

Risposte

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

Un modo per gestire questo caso senza allocare un ulteriore Vecè utilizzare AsRef<[u8]>:

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

All'interno della funzione, puoi utilizzare .as_ref()per convertire ciascuno degli argomenti in un file &[u8].

( parco giochi )

2 Locke Nov 08 2020 at 16:11

Dal punto di vista della memoria questo non ha molto senso. Per creare una sezione, i dati da tagliare devono prima esistere in memoria. Tuttavia, per prendere una fetta di &[u8], devi prima avere una struttura dati Vec<&[u8]>da cui prendere la fetta.

In altre parole, per fare ciò, devi prima allocare lo spazio per Vec<&[u8]>o [&[u8]; N]e riempirlo con le fette. Ciò vanifica in qualche modo lo scopo dell'uso delle sezioni poiché le sezioni sono destinate alla memoria di riferimento esistente sul posto. Considera invece l'utilizzo &[Vec<u8>]per la tua funzione.

Se è importante avere sezioni nel secondo livello o non sei in grado di modificare la funzione, puoi eseguire la conversione Vec<Vec<u8>>in &[&[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[..]);