Rust'ta u32 dizisini Vec <u8> 'e dönüştür
Rust'ta bir dizi u32değer almak, her birini big endian'da dört bayta dönüştürmek ve bir Vec<u8>sonuç elde etmek için birleştirmek istiyorum . Misal:
let input: [u32; 5] = [
0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
(... Do some data conversion work ...)
let output: Vec<u8> = vec![
0x67, 0x45, 0x23, 0x01,
0xEF, 0xCD, 0xAB, 0x89,
0x98, 0xBA, 0xDC, 0xFE,
0x10, 0x32, 0x54, 0x76,
0xC3, 0xD2, 0xE1, 0xF0,
];
Hepsi aynı cevabı veren birkaç çalışma kodum var.
Algoritma A (döngü için):
let mut output = Vec::<u8>::new();
for val in &input{
output.extend_from_slice(&val.to_be_bytes());
}
Algoritma B (her biri için):
let mut output = Vec::<u8>::new();
input.iter().for_each(|val| output.extend_from_slice(&val.to_be_bytes()));
Algoritma C (kat-ekleme):
let output = input.iter().fold(Vec::<u8>::new(),
|mut acc, val| {acc.extend_from_slice(&val.to_be_bytes()); acc});
Algoritma D (düz harita):
let output: Vec<u8> = input.iter().flat_map(|val| val.to_be_bytes().to_vec()).collect();
Görevi gerçekleştirmenin daha da kısa ve daha net bir yolu var mı? Belki algoritma D' to_vec()lerinden bir şekilde kaçınılabilir?
Hız bir sorun değildir çünkü bu kod yalnızca birkaç kez çalışır ve giriş dizisi uzunluğu 5 olarak sabitlenmiştir.
Yanıtlar
Algoritma A bana en açık gibi görünüyor. Vec::with_capacityTahsisatı önlemek için bir iyileştirme kullanılması olabilir . Aslında, Rust'taki dizilerin kullanımı şu anda biraz hantaldır.
Benim tavsiyem, onu bir fonksiyona sarmak ve daha sonra bunun için endişelenmemek olacaktır:
pub fn to_bytes(input: &[u32]) -> Vec<u8> {
let mut bytes = Vec::with_capacity(4 * input.len());
for value in input {
bytes.extend(&value.to_be_bytes());
}
bytes
}
#[cfg(test)]
mod tests {
#[test]
fn to_bytes() {
use super::*;
assert_eq!(to_bytes(&[]), &[]);
let input = &[0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
let output = &[
0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89, 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32,
0x54, 0x76, 0xC3, 0xD2, 0xE1, 0xF0,
];
assert_eq!(to_bytes(input), output);
}
}
( oyun alanı )