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

Nov 08 2020

Tengo una función que toma una serie de cadenas de bytes: &[&[u8]]pero quiero llamarla con un argumento de tipo Vec<Vec<u8>>. Llamar a la función de esta manera:

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

se convierte fooen un segmento, pero no en los valores que contiene. ¿Hay alguna forma de hacer esta conversión de manera fácil y eficiente? ¿O puedo cambiar el tipo de argumento de la función para evitar casos como este?

Respuestas

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

Una forma de manejar este caso sin asignar un adicional Veces usar AsRef<[u8]>:

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

Dentro de la función, puede usar .as_ref()para convertir cada uno de los argumentos a &[u8].

( patio de recreo )

2 Locke Nov 08 2020 at 16:11

Desde la perspectiva de la memoria, esto no tiene mucho sentido. Para crear un segmento, los datos que se cortan primero deben existir en la memoria. Sin embargo, para tomar una porción &[u8], primero debe tener alguna estructura de datos de la que Vec<&[u8]>pueda tomar la porción.

En otras palabras, para hacer esto, primero debe asignar espacio para Vec<&[u8]>o [&[u8]; N]y llenarlo con sectores. Esto frustra de alguna manera el propósito de usar segmentos, ya que los segmentos están destinados a la memoria de referencia existente en su lugar. Considere usar &[Vec<u8>]para su función en su lugar.

Si tener cortes en la segunda capa es importante o no puede editar la función, puede hacer lo siguiente para convertir Vec<Vec<u8>>a &[&[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[..]);