克隆&[u32]至[u32]

问题描述

我正在做一些编码练习,问题是定义一个参数为&[u32]的函数。我想对其进行一些更改,因此最好的方法是将其复制到可变变量中,以便我可以自由更改。我尝试使用let v = a.clone(),但它一直给我一个&[u32]而不是[u32],我知道它显然给了&[u32],但我真的不知道如何将其转换为[ u32]。我尝试查找它,但找不到任何东西! 请帮忙!非常感谢!

解决方法

&[u32]由(指针,长度)对表示,其中指针指向整数数组,而长度记录整数。另一方面,[u32]不包含指针,它的字面意思是“这里有一定数量的u32”。 Rust将此类称为unsized,您对它们的处理方式非常有限-通常必须间接引用它们。因此,如果要复制切片以使其突变,则需要创建自己的(指针,长度)对。

正如您所发现的,在clone()上调用&[u32]并没有完成任何事情,因为它会克隆共享的 reference ,即为您提供了另一个指针/长度对实例指向相同的数据。您想要的是实际副本。

通常复制&[u32]不会导致产生新的&[u32],因为&是对其他人拥有的数据的引用。由于您需要创建数据的全新副本,因此需要有人来拥有它。这就是Box的用途,所以您想要的是Box<[u32]>,它与&[u32](一个(指针,长度)对)的堆栈表示形式完全相同。将&[T]复制到新的Box<T>中最简单的方法是使用to_vec方法来创建临时Vec<T>Vec<T>Box<[T]>类似,除了它还跟踪内存的容量(分配了多少数据),从而可以有效地添加新元素。由于您不会添加新元素,因此可以立即将向量转换为框:

fn mutate(x: &[u32]) {
    // copy x into Box<[u32]> through a temporary Vec
    let mut copy: Box<[u32]> = x.to_vec().into_boxed_slice();

    // now that we own the copy,we can create &mut [u32] into it
    let mref: &mut [u32] = copy.as_mut();
    mref[0] = 10;  // ...

    // at the end of scope,the slice we own is deallocated
}

Vec<T>转换为Box<T>是有效的,因为Vec使用的存储已被Box重用。区别只是Vec使用的“容量”计数器被丢弃,因此重新计算值再次在堆栈上由(指针,长度)对表示,而不是由(指针,长度,容量)三元组表示。