Converter Vec <Vec <u8>> em & [& [u8]] [duplicar]

Nov 08 2020

Tenho uma função que usa um certo número de cadeias de bytes: &[&[u8]]mas quero chamá-la com um argumento do tipo Vec<Vec<u8>>. Chamando a função assim:

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

converte fooem uma fatia, mas não nos valores que ela contém. Existe uma maneira de fazer essa conversão de forma fácil e eficiente? Ou posso alterar o tipo do argumento da função para evitar casos como este?

Respostas

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

Uma maneira de lidar com este caso sem alocar um adicional Vecé usar AsRef<[u8]>:

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

Dentro da função, você pode usar .as_ref()para converter cada um dos argumentos em um &[u8].

( playground )

2 Locke Nov 08 2020 at 16:11

Do ponto de vista da memória, isso não faz muito sentido. Para criar uma fatia, os dados sendo fatiados devem primeiro existir na memória. No entanto, para obter uma fatia de &[u8], primeiro você precisa ter alguma estrutura de dados, como Vec<&[u8]>retirar a fatia.

Em outras palavras, para fazer isso, você precisa alocar espaço para Vec<&[u8]>ou [&[u8]; N]e preenchê-lo com fatias primeiro. Isso anula um pouco o propósito de usar fatias, uma vez que as fatias são destinadas à memória de referência existente no local. Considere usar &[Vec<u8>]para a sua função.

Se ter fatias na segunda camada for importante ou se você não conseguir editar a função, pode fazer o seguinte para convertê Vec<Vec<u8>>-la &[&[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[..]);