问题描述
我正在做一些编码练习,问题是定义一个参数为&[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
使用的“容量”计数器被丢弃,因此重新计算值再次在堆栈上由(指针,长度)对表示,而不是由(指针,长度,容量)三元组表示。