在Rust中,JavaScript的DataView与什么等效?

在Rust中,JavaScript的DataView与什么等效?,rust,Rust,在JavaScript中,当您需要通过以下方式访问内存块时,使用DataView: 不同宽度类型的uint8、uint16、uint32、浮动32等 不结盟数据 比端度 DataView通常用于网络代码、解析和创建二进制文件格式以及实现虚拟机。虽然前两种只能通过顺序访问来实现,但使用DataView作为RAM的虚拟机需要能够自由地随机访问它 在Rust有相应的库吗?我见过,但它们似乎更适合流式/顺序访问,而不是免费随机访问。作为一种系统语言,Rust本机具有与原始内存交互的能力,无需特定的包装器

在JavaScript中,当您需要通过以下方式访问内存块时,使用DataView:

不同宽度类型的uint8、uint16、uint32、浮动32等 不结盟数据 比端度 DataView通常用于网络代码、解析和创建二进制文件格式以及实现虚拟机。虽然前两种只能通过顺序访问来实现,但使用DataView作为RAM的虚拟机需要能够自由地随机访问它


在Rust有相应的库吗?我见过,但它们似乎更适合流式/顺序访问,而不是免费随机访问。

作为一种系统语言,Rust本机具有与原始内存交互的能力,无需特定的包装器

因此,从内存中读取u32只需要少量的不安全信息:

其中包括:

执行转换。 平均处理未对齐的访问,而不是惊慌失措。 具有明确的终结性。 不过,它实际上只考虑了基本类型,而这正是字节板条箱的作用所在

例如,让我们解码一个:

它使用标准库中的struct及其从字节中实现的trait

您可以从内存的任意点开始,在字节片&[u8]周围创建光标;从中读取会推进它,为下一次读取定位它,它将处理对齐、端点和边界检查

注意:遗憾的是,似乎没有版本返回选项;如果这是一个问题,我可能会延长它


因此,我认为您对列出的板条箱有了正确的想法,它们涵盖了您列出的所有需求。

作为一种系统语言,Rust本机具有与原始内存交互的能力,而不需要特定的包装器

因此,从内存中读取u32只需要少量的不安全信息:

其中包括:

执行转换。 平均处理未对齐的访问,而不是惊慌失措。 具有明确的终结性。 不过,它实际上只考虑了基本类型,而这正是字节板条箱的作用所在

例如,让我们解码一个:

它使用标准库中的struct及其从字节中实现的trait

您可以从内存的任意点开始,在字节片&[u8]周围创建光标;从中读取会推进它,为下一次读取定位它,它将处理对齐、端点和边界检查

注意:遗憾的是,似乎没有版本返回选项;如果这是一个问题,我可能会延长它


因此,我认为您对所列板条箱的想法是正确的,它们涵盖了您提出的所有要求。

为什么rust应该有这种等效物?描述你的问题,这里你只是把一个概念从一种语言转换到另一种语言。Rust是强类型,一般不需要dataView。@Stargateur当然一般不需要它,但在某些情况下它是有帮助的,正如我上面所述。我的特定用例是针对虚拟机的,但这不一定是问题所在。我可以使用u8数组手动编写我自己的代码,但我想知道其他具有类似用例的人会做什么。为什么rust会有这种等价物?描述你的问题,这里你只是把一个概念从一种语言转换到另一种语言。Rust是强类型,一般不需要dataView。@Stargateur当然一般不需要它,但在某些情况下它是有帮助的,正如我上面所述。我的特定用例是针对虚拟机的,但这不一定是问题所在。我可以使用u8数组手动编写自己的代码,但我想知道其他使用类似用例的人会做什么。谢谢你,这非常有帮助。所以你的建议是在需要随机访问时使用游标并搜索?我想大多数情况下,您从每次搜索中读取的值都不止一个,因此与每次显式传递地址的JS DataView模式相比,这不会产生更多的代码,甚至可能更少的代码。@curiousdannii:事实上,我只会动态构建光标。从一个内存开始:&[u8],我将使用split_atoffset.1跳转切片它,并在上面构建一个游标:让mut Cursor=Cursor::newmemory.split_atoffset.1;。当然,这避免了必须保留光标,并假定您已经保留了内存:谢谢,这非常有帮助。所以你的建议是在需要随机访问时使用游标并搜索?我想大多数情况下,您从每次搜索中读取的值都不止一个,因此与每次显式传递地址的JS DataView模式相比,这不会产生更多的代码,甚至可能更少的代码。@curiousdannii:事实上,我只会动态构建光标。从一个内存开始:&[u8],我将使用sp跳转切片它 点燃\u atoffset.1并在顶部构建一个游标:让mut Cursor=Cursor::newmemory.split\u atoffset.1;。这避免了必须保留光标,并假定您已经保留了内存,当然:
fn read_u32(bytes: &[u8]) -> u32 {
    assert!(bytes.as_ptr() as usize % std::mem::align_of::<u32>() == 0);
    assert!(bytes.len() >= 4);

    unsafe { *(bytes.as_ptr() as *const u32) }
}
fn read_u32(bytes: &[u8]) -> u32 { LittleEndian::read_u32(bytes) }
use std::io::Cursor;
use bytes::buf::Buf;

struct UdpHeader {
    src_port: u16,
    dst_port: u16,
    length: u16,
    checksum: u16,
}

fn read_udp_header<T: AsRef<[u8]>>(bytes: &mut Cursor<T>) -> UdpHeader {
    UdpHeader {
        src_port: bytes.read_u16_be(),
        dst_port: bytes.read_u16_be(),
        length: bytes.read_u16_be(),
        checksum: bytes.read_u16_be(),
    }
}