Rust에서 u32 배열을 Vec <u8>로 변환

Oct 07 2020

Rust에서는 u32값 배열을 가져 와서 각각을 빅 엔디안의 4 바이트로 변환하고 연결하여 Vec<u8>결과 를 얻고 싶습니다 . 예:

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,
];

모두 동일한 대답을 제공하는 작업 코드가 여러 개 있습니다.

알고리즘 A (for-loop) :

let mut output = Vec::<u8>::new();
for val in &input{
    output.extend_from_slice(&val.to_be_bytes());
}

알고리즘 B (각각) :

let mut output = Vec::<u8>::new();
input.iter().for_each(|val| output.extend_from_slice(&val.to_be_bytes()));

알고리즘 C (접기-추가) :

let output = input.iter().fold(Vec::<u8>::new(),
    |mut acc, val| {acc.extend_from_slice(&val.to_be_bytes()); acc});

알고리즘 D (플랫 맵) :

let output: Vec<u8> = input.iter().flat_map(|val| val.to_be_bytes().to_vec()).collect();

작업을 수행하는 더 짧고 명확한 방법이 있습니까? 알고리즘 D to_vec()는 어떻게 든 피할 수 있을까요?

이 코드는 몇 번만 실행되고 입력 배열 길이는 5로 고정되므로 속도는 문제가되지 않습니다.

답변

2 L.F. Oct 07 2020 at 19:32

알고리즘 A가 가장 명확 해 보입니다. Vec::with_capacity할당을 피하기 위해 사용하는 것이 개선 될 수 있습니다 . 사실, Rust의 배열은 현재 사용하기 다소 번거 롭습니다.

내 조언은 함수로 감싸고 나중에 걱정하지 않는 것입니다.

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);
    }
}

( 놀이터 )