如何在Rust中连接静态切片?

10
我有两片静态的 u8 数组,我想实现一个函数将它们拼接在一起。类似下面这样的代码:
fn concat_u8(first: &'static [u8], second: &'static [u8]) -> &'static [u8] {
    &[&first[..], &second[..]].concat()
}

编译器显示我错误信息: 返回对当前函数拥有的数据的引用。这是因为分配的内存将在函数结束时释放。
如何“强制”生命周期为静态? 编辑 我有一个长时间运行的进程。
在启动时,该进程会处理一些输入以计算结果(例如concat_u8函数)。结果是u8的片段,并将在处理过程中始终以只读方式使用。 concat_u8函数无法在“内部启动事件”之后调用。
我不想使用Box,因为动态分配意味着有点额外开销(也许无法测量?)并将结果存储为&[u8]
我有没有机会这样做?
我有没有机会在不使用unsafe块的情况下这样做?

如果你说出为什么想要那样做,我认为你会得到更好的答案。 - Stargateur
1
“并将结果存储为&[u8]”。切片仅借用一些数据,它不能存储超过其原始长度的数据。这看起来越来越像一个XY问题。 - E net4
1个回答

21

无法将两个具有静态寿命的切片连接到一个新的具有静态寿命的切片中而不泄漏内存。

切片在内存中按顺序存储。连接具有静态寿命的两个切片需要将它们复制到新分配的内存中,因为结果也需要是连续的。这个新分配的内存必然属于当前函数,因此您不能返回对它的引用。

您需要将内存的所有权转移回调用者:

pub fn concat_u8(first: &[u8], second: &[u8]) -> Vec<u8> {
    [first, second].concat()
}

现在不再需要要求输入参数具有静态生命周期,也可能根本不需要实现此函数,因为调用它并不比将代码直接内联更简短或更清晰。

如上所述,如果由于某种原因您需要一个 &'static [u8] 而不是一个 Vec<u8>,则可以使用 leak() 函数泄露向量。很少有这样做的理由,而访问静态切片与访问向量没有任何速度优势。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接