如何复制一个 &[u8] 切片?

8

如何复制 &[u8] 切片的内容?

我正在尝试编写一个函数,它以缓冲区作为输入,将每个字节与给定的密钥进行异或操作,并返回最终结果。

我不希望它破坏输入缓冲区。

pub fn xor_buffer(buffer_in: &[u8], key: char) -> &[u8] {

    let mut buffer_out = buffer_in.clone();

    for byte in &mut buffer_out[..] {
        *byte ^= key as u8;
    }

    buffer_out
}

这段代码会产生以下的编译时错误:

src/test.rs:29:22: 29:32 error: cannot borrow immutable borrowed content `*buffer_out` as mutable
src/test.rs:29     for byte in &mut buffer_out[..] {
                                               ^~~~~~~~~~

我知道我一定做错了什么。
任何帮助将不胜感激。
1个回答

18

首先,无论是哪种类型的 T,都不能直接 clone 一个 [T]。第三行代码并不是在克隆缓冲区,而是在克隆指向它的指针。如果你将绑定改为

let mut buffer_out: &[u8] = buffer_in.clone();

如果您想要一个切片的独立副本,您需要将其转换为Vec或其他拥有容器类型;可以使用buffer_in.to_owned()来实现这一点(它通常会从一种借用的东西转换为拥有的等效物)。

其次,您不能返回对函数内创建的内容的引用。真的不行。不,真的不行。甚至不包括那个和那个。只有在返回值直接从您的参数中借用时(例如&[u8]),才能返回借用。但这里不是这种情况,因此返回类型必须是Vec<u8>或其他拥有的类型。

第三,复制数组,然后再进行修改可能会效率低下。理想情况下,您希望尽可能少地进行修改(同时避免诸如不必要分配之类的更慢的操作)。可以使用迭代器来实现这一点。

第四,无法保证key的值实际上适合于u8。您应该将其更改为key: u8,以向调用者明确有效值范围。

因此,总体来说:

pub fn xor_buffer(buffer_in: &[u8], key: u8) -> Vec<u8> {
    // Get an iterator of `&u8`s from `buffer_in`.
    buffer_in.iter()
        // Replace each element with the xor'ed value.
        .map(|byte| *byte ^ key)
        // Collect the iterator into an owned collection.
        .collect()
}

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