我有一个带有一些固定大小数组的 struct :

struct PublicHeaderBlock_LAS14 {
    file_signature: [u8; 4],
    file_source_id: u16,
    global_encoding: u16,
    project_id_data_1: u32,
    project_id_data_2: u16,
    project_id_data_3: u16,
    project_id_data_4: [u8; 8],
    version_major: u8,
    version_minor: u8,
    systemIdentifier: [u8; 32], // ...
}

我从一个文件中读取字节到一个固定大小的数组中,并将这些字节一点一点地复制到 struct 中.

fn create_header_struct_las14(&self, buff: &[u8; 373]) -> PublicHeaderBlock_LAS14 {
    PublicHeaderBlock_LAS14 {
        file_signature: [buff[0], buff[1], buff[2], buff[3]],
        file_source_id: (buff[4] | buff[5] << 7) as u16,
        global_encoding: (buff[6] | buff[7] << 7) as u16,
        project_id_data_1: (buff[8] | buff[9] << 7 | buff[10] << 7 | buff[11] << 7) as u32,
        project_id_data_2: (buff[12] | buff[13] << 7) as u16,
        project_id_data_3: (buff[14] | buff[15] << 7) as u16,
        project_id_data_4: [buff[16], buff[17], buff[18], buff[19], buff[20], buff[21], buff[22], buff[23]],
        version_major: buff[24],
        version_minor: buff[25],
        systemIdentifier: buff[26..58]
    }
}

最后一行(systemIdentifier)不起作用,因为在 struct 中它是[u8; 32],而buff[26..58]是切片.我能不能把一个切片转换成一个固定大小的数组,比如在一个范围内,而不是像我刚才说的file_signature那样?

推荐答案

没有safe种方法可以用切片初始化 struct 中的array.您需要求助于直接在未初始化内存上运行的unsafe块,或者使用以下两种先初始化再变异策略之一:

构造所需的数组,然后使用它初始化 struct .

struct Foo {
    arr: [u8; 32],
}

fn fill(s: &[u8; 373]) -> Foo {
    let mut a: [u8; 32] = Default::default();
    a.copy_from_slice(&s[26..58]);
    Foo { arr: a }
}

或者初始化 struct ,然后在 struct 内部变异array.

#[derive(Default)]
struct Foo {
    arr: [u8; 32],
}

fn fill(s: &[u8; 373]) -> Foo {
    let mut f: Foo = Default::default();
    f.arr.copy_from_slice(&s[26..58]);
    f
}

如果你的 struct 有很多成员,第一个更干净.如果编译器不能优化中间副本,那么第二个可能会更快一些.但如果这是程序的性能瓶颈,您可能会使用unsafe方法.

Rust相关问答推荐

为什么在Rust struct 中只允许最后一个字段具有动态大小的类型

有条件默认实现

把Vector3变成Vector4的绝妙方法

如何创建引用构造函数拥有的变量的对象?

将大小为零的类型实例存储到空指针中

定义采用更高级类型泛型的性状

为什么铁 rust S似乎有内在的易变性?

函数内模块的父作用域的访问类型

带参考文献的 rust 元组解构

`RwLockWriteGuard_,T`不实现T实现的特征

如何在嵌套的泛型 struct 中调用泛型方法?

Rust移动/复制涉及实际复制时进行检测

如何实现Deref;多次;?

在为第三方 struct 实现第三方特征时避免包装器的任何方法

Nom 解析器无法消耗无效输入

Rust 中的内存管理

在描述棋盘时如何最好地使用特征与枚举

无法把握借来的价值不够长寿,请解释

TinyVec 如何与 Vec 大小相同?

为什么这里需要类型注解?