当前位置: 首页 > 知识库问答 >
问题:

切片到固定大小的数组[重复]

甄伟兆
2023-03-14

我有一个结构与一些固定大小的数组

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], // ...
}

我从一个文件中读取字节到一个固定大小的数组中,并将这些字节逐位复制到结构中。

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)不起作用,因为在结构中它是一个[u8;32],而buff[26..58]是一个切片。我是否可以返回将一个片转换为一个固定大小的数组,就像在一个范围内那样,而不是像我所做的那样说file\u signature

共有2个答案

伍耀
2023-03-14

感谢@malbarbo,我们可以使用此帮助功能:

use std::convert::AsMut;

fn clone_into_array<A, T>(slice: &[T]) -> A
    where A: Sized + Default + AsMut<[T]>,
          T: Clone
{
    let mut a = Default::default();
    <A as AsMut<[T]>>::as_mut(&mut a).clone_from_slice(slice);
    a
}

要获得更简洁的语法:

fn main() {
    let original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    let e = Example {
        a: clone_into_array(&original[0..4]),
        b: clone_into_array(&original[4..10]),
    };

    println!("{:?}", e);
}

只要T: Default Clone.

它将恐慌如果目标数组和传入的切片不具有相同的长度,因为从切片克隆\u具有相同的长度。

魏凯捷
2023-03-14

没有安全的方法来初始化具有切片的结构中的数组。您需要求助于直接在未初始化内存上运行的不安全块,或者使用以下两种先初始化后变异策略之一:

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

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

或者初始化结构,然后在结构内部变异数组。

#[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
}

如果您的结构有许多成员,那么第一个更干净。如果编译器不能优化中间副本,那么第二个副本可能会快一点。但是如果这是程序的性能瓶颈,您可能会使用不安全的方法。

 类似资料:
  • 相关:切片到固定大小的数组,但是我正在寻找更具体的形式。 理想情况下,我希望构建一个具有以下签名的函数: 因为这还不可能(因为非类型参数不是一件事),所以我不想让函数直接接受数组: 用代替。 以下是我迄今为止最有希望的尝试: 然而,我错过了允许数组强制切片的特性(提示:这不是)。 只要我同意函数只适用于小数组,有没有办法使用安全代码构建这样的函数?

  • 问题内容: 我正在尝试将固定大小的数组转换为可变大小的数组(切片): 但是编译器抛出错误: 我应该如何转换? 问题答案: 使用让您在阵列上切片。另请参阅此博客文章,以获取有关数组和切片的更多信息。

  • 问题内容: 在Swift中,我试图创建一个由64个SKSpriteNode组成的数组。我想先将其初始化为空,然后将Sprites放在前16个单元格中,然后将最后16个单元格中(模拟象棋游戏)。 根据我在文档中了解的内容,我期望会出现以下情况: 要么 但这是行不通的。在第二种情况下,我收到一条错误消息:“尚不支持定长数组”。那可以是真的吗?对我来说,这听起来像是一项基本功能。我需要通过它们的索引直接

  • 问题内容: 我想知道如何初始化一个数组(或列表),但尚未填充值,以具有定义的大小。 例如在C中: 我该如何在python中做到这一点? 谢谢。 问题答案: 您可以使用:

  • 问题内容: 我需要将图片调整为固定大小。但它必须将宽度和高度之间的因素。 说我要调整从图片到 我现在要做的是: 现在我考虑最小的因素。 从那以后我一直都有正确的宽度。但是身高还是。 如何在不破坏图片的情况下降低高度? 我需要修剪吗?如果可以,怎么办? 问题答案: 这个解决方案与Can BerkGüder的解决方案基本相同,但是花了一些时间写和发表评论后,我才觉得喜欢发布。 此功能创建的缩略图与您提

  • 问题内容: 我在这里阅读了一些帖子,然后开始了为什么有些人这样做 代替 第二个不是更好,因为它仅创建一个对象,而第一个可能创建多个对象(即使它并没有浪费多少内存)?还是我错了?有什么区别吗? 问题答案: 最大的区别在于值随时间变化的方式,因此您选择的值应取决于您要对代码执行的操作。 如果您只是简单地调用代码,它将按照您的预期进行- 将首选尺寸设置为500x500。但是,应用程序中的其他代码可能会用