连接字节数组而不分配

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

我想将一个“标记”字节附加到字节切片上,以确保它在解析时以换行字节结尾。这是我认为它可能的样子:

fn parse(inp: &[u8]) {
    let workable_array = inp.basic_append(b'\n');
}

当访问一个字节超出原始输入的长度时,它将进入添加的字节。之后我将在纯只读上下文中使用新数组。

我知道切片上的 concat 方法,但这在内部分配了一个全新的向量,这似乎不必要地昂贵。特别是当输入字符串可能非常大时。

string rust byte
1个回答
0
投票

如果您要求的操作需要一个

&[u8]
并返回另一个包含换行符字节的
&[u8]
,而无需重新分配,那么答案是这是不可能的。
&[u8]
always 连续内存,因此换行符物理上必须位于切片的末尾,这只能通过重新分配来实现。此外,使用
&[u8]
切片是不可能的,因为它不是
mut
able.

然而,您实际上可以使用 iterators 实现类似的效果。在生成所有其他字节后,它不会分配并简单地提供另一个换行字节。

fn append_newline(data: impl Iterator<Item = u8>) -> impl Iterator<Item = u8> {
    data.chain(std::iter::once(b'\n'))
}

fn main() {
    let s = "Hello";
    let s_iter_with_newline = append_newline(s.bytes());
    for b in s_iter_with_newline {
        println!("{:?}", b as char);
    }
}
'H'
'e'
'l'
'l'
'o'
'\n'

当然,这与需要

&[u8]
作为参数的函数不兼容。


补充说明:

  • 听起来您的输入有时包含换行符,有时不包含。从有换行符的换行符中删除换行符比将它添加到没有换行符的换行符要容易得多。也许改变你的解析算法,所以它需要没有换行符的输入?
  • 你在这里使用
    &[u8]
    来进行听起来像字符串操作的操作。请注意,Rust
    char
    s 是 not
    u8
    s - 它们是可变大小的 UTF-8 条目。这就是
    &str
    /
    String
    类型存在的原因。将它们用于字符串处理,因为它们可以处理特殊字符,与
    &[u8]
    不同。当然,您在这里遇到的
    '\n'
    问题仍然存在
    str
    ,如果不重新分配它仍然是不可能的。
© www.soinside.com 2019 - 2024. All rights reserved.