为什么原始部分不符合任何字节顺序?

Why does the raw parts not correspond to either endianness?

我正在尝试尽可能多地优化对 u8 数组中的 u32 切片执行的操作。因此,我正在测试不同的选项(循环、迭代器、使用 ByteOrder crate 等) 作为这些测试的一部分,我还想检查是否可以使用 from_raw_parts 标准函数改进它。 这是我的代码:

use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;

fn main(){
let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
let random_bytes = random_bytes.as_slice();

let view = &random_bytes as *const _ as *const u32;
let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
println!("{:x?}", slice);
println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", &random_bytes[0..4]);
}

我本来希望两个 Little 或 Big endian 中至少有一个等于第一个打印,但事实并非如此,例如示例输出

[d951db30]
143600ff
ff003614
[ff, 0, 36, 14] 

我做错了什么?

问题在这里:

let view = &random_bytes as *const _ as *const u32;

切片是一个 2 机器字结构,包含指向数据的指针和作为成员的元素计数。 通过执行 &random_bytes,您正在引用此切片结构(它本身包含一个指针和长度),而不是获取底层指针。

切片有一个 as_ptr 方法,该方法 returns 指向数据本身的指针。当您使用它时,您的代码可以正常运行:

use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;

fn main(){
    let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
    let random_bytes = random_bytes.as_slice();
    
    let view = random_bytes.as_ptr() as *const u32;
    let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
    println!("{:x?}", slice);
    println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
    println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
    println!("{:x?}", &random_bytes[0..4]);
}

操场上的输出:

[684a2f5b]
684a2f5b
5b2f4a68
[5b, 2f, 4a, 68]