我想将一个“标记”字节附加到字节切片上,以确保它在解析时以换行字节结尾。这是我认为它可能的样子:
fn parse(inp: &[u8]) {
let workable_array = inp.basic_append(b'\n');
}
当访问一个字节超出原始输入的长度时,它将进入添加的字节。之后我将在纯只读上下文中使用新数组。
我知道切片上的 concat 方法,但这在内部分配了一个全新的向量,这似乎不必要地昂贵。特别是当输入字符串可能非常大时。
如果您要求的操作需要一个
&[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
,如果不重新分配它仍然是不可能的。