从匹配表达式返回切片(或未知大小的数组)

问题描述 投票:0回答:1

我正在尝试实现以下想法:

let command = ...;

let request = match subcommand {
    Some(x) => [command, x as u8, (x >> 8) as u8],
    None => [command],
};

request
应该是 1(如果没有子命令)或 3(如果有 2 字节子命令)的数组。显然这种方法不起作用,因为匹配表达式的分支“返回”不同类型([u8;1] 或 [u8;3]);

我的逻辑后续行动是使用切片:

let request: &[u8] = match subcommand {
    Some(x) => &[...],
    None => &[...],
};

这对于常量值(例如

&[0, 0, 0]
)效果很好,但是当我尝试使用变量构建数组时,它会失败并显示
temporary value dropped while borrowed

我知道在这种情况下我的引用正在转义到上级代码块,但是有没有办法解决它(即一些生命周期注释?)

预先创建缓冲区并使用切片确实有效,但感觉不是最佳。

arrays rust slice variable-length-array
1个回答
0
投票

有多种方法可以做到这一点。这里有一些建议。

  1. 只需使用
    Vec
    (或
    Box<[u8]>
    )。是的,它的效率较低,但这对你来说重要吗?这可能是最明确的解决方案。
  2. 使用堆栈分配的向量,例如
    ArrayVec
  3. 如果类型有一个简单的默认值,则在外部作用域中有一个数组并初始化其中的一部分,并返回一个切片到这部分:
let mut scratch_space = [0; 3];
let request = match subcommand {
    Some(x) => {
        let data = &mut scratch_space[..3];
        data.copy_from_slice(&[command, x as u8, (x >> 8) as u8]);
        data
    },
    None => {
        scratch_space[0] = command;
        &scratch_space[..1]
    },
};
  1. 如果这是不可能的,请声明多个这样的数组并仅初始化一个。那就是:
let scratch_space1;
let scratch_space2;
let request = match subcommand {
    Some(x) => {
        scratch_space1 = [command, x as u8, (x >> 8) as u8];
        &scratch_space1[..]
    },
    None => {
        scratch_space2 = [command];
        &scratch_space2[..]
    },
};
© www.soinside.com 2019 - 2024. All rights reserved.