Vec <Vec <u8>> & [& [u8]] [çoğalt] biçimine dönüştür

Nov 08 2020

Birkaç bayt dizesi &[&[u8]]alan bir işlevim var: ancak onu bir tür bağımsız değişkenle çağırmak istiyorum Vec<Vec<u8>>. İşlevi şöyle çağırmak:

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

foobir dilime dönüştürür , ancak içerdiği değerleri değil. Bu dönüşümü kolay ve verimli bir şekilde yapmanın bir yolu var mı? Veya bunun gibi durumlardan kaçınmak için işlev bağımsız değişkeninin türünü değiştirebilir miyim?

Yanıtlar

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

Ek bir tahsisat ayırmadan bu durumu ele almanın bir yolu Vecşudur AsRef<[u8]>:

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

Fonksiyonun .as_ref()içinde, argümanların her birini bir &[u8].

( oyun alanı )

2 Locke Nov 08 2020 at 16:11

Hafıza açısından bakıldığında bu pek mantıklı değil. Bir dilim oluşturmak için, dilimlenen verilerin önce bellekte bulunması gerekir. Bununla birlikte, bir dilim almak için &[u8], önce Vec<&[u8]>dilimi almak gibi bir veri yapısına sahip olmanız gerekir .

Başka bir deyişle, bunu yapmak için önce alan ayırmanız Vec<&[u8]>veya [&[u8]; N]dilimlerle doldurmanız gerekir. Bu, dilimlerin kullanım amacını bir şekilde bozar çünkü dilimler, mevcut referans belleğe yöneliktir. &[Vec<u8>]Bunun yerine işleviniz için kullanmayı düşünün .

İkinci katmanda dilimlerin olması önemliyse veya işlevi düzenleyemiyorsanız, dönüştürmek Vec<Vec<u8>>için aşağıdakileri yapabilirsiniz &[&[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[..]);