Каков идиоматический способ перебора байтов целого числа в Rust?

Я попробовал такой фрагмент кода для перебора байтов u64:

let mut message: u64 = 0x1234123412341234;
let msg = &message as *mut u8;

for b in 0..8 {
    // ...some work...
}

К сожалению, Rust не поддерживает такое C-подобное индексирование.


person hedgar2017    schedule 27.05.2018    source источник
comment
этот код на C будет реализован поведением, поэтому трудно точно понять, что вы хотите. И кстати, если говорить о строгом соответствии, то этот код на C будет иметь неопределенное поведение.   -  person Stargateur    schedule 27.05.2018
comment
@Stargateur char (и [un]signed char) является явным исключением из строгого правила псевдонимов, поэтому этот код легко написать в строгом соответствии с C. Фактическое поведение определяется реализацией, но не неопределенно.   -  person trentcl    schedule 27.05.2018


Ответы (2)


Хотя transmute возможно (см. ответ @Tim), лучше использовать контейнер порядка байтов, чтобы гарантировать порядок следования байтов:

extern crate byteorder;

use byteorder::ByteOrder;

fn main() {
    let message = 0x1234123412341234u64;
    let mut buf = [0; 8];
    byteorder::LittleEndian::write_u64(&mut buf, message);

    for b in &buf {
         // 34, 12, 34, 12, 34, 12, 34, 12, 
         print!("{:X}, ", b);
    }

    println!("");

    byteorder::BigEndian::write_u64(&mut buf, message);

    for b in &buf {
         // 12, 34, 12, 34, 12, 34, 12, 34, 
         print!("{:X}, ", b);
    }
}

(Постоянная ссылка на игровую площадку)

person mcarton    schedule 27.05.2018

Безопасно преобразовать u64 в массив [u8; 8]:

let message_arr: [u8; 8] = unsafe { mem::transmute(message) };
for b in &message_arr {
    println!("{}", b)
}

Посмотрите это в действии на игровой площадке.

person Tim Diekmann    schedule 27.05.2018