Vector 具有预定义容量的Vec上设置透镜操作的安全性

Vector 具有预定义容量的Vec上设置透镜操作的安全性,vector,rust,Vector,Rust,在已声明容量的Vec上调用set\u len安全吗?像这样: let vec = unsafe { let temp = Vec::with_capacity(N); temp.set_len(N); temp } 在添加任何元素之前,我需要向量的大小为N 查看文档: 我有点困惑。文档说,带容量的不会改变长度,set\u len说调用者必须确保向量具有适当的长度。这安全吗 我之所以需要这样做,是因为我在寻找一种方法来声明大小为N的可变缓冲区(&mut[T]),

在已声明容量的
Vec
上调用
set\u len
安全吗?像这样:

let vec = unsafe {
    let temp = Vec::with_capacity(N);
    temp.set_len(N);
    temp
}
在添加任何元素之前,我需要向量的大小为N

查看文档:

我有点困惑。文档说,带容量的
不会改变长度,
set\u len
说调用者必须确保向量具有适当的长度。这安全吗

我之所以需要这样做,是因为我在寻找一种方法来声明大小为N的可变缓冲区(
&mut[T]
),而
Vec
似乎最适合这个方案。我只是想避免让我的类型实现
vec![0;n]
将带来。

如果“我需要向量大小为n”的意思是需要为10个元素分配内存,那么具有容量的
已经在这样做了

如果您的意思是希望有一个长度为10的向量(但不确定为什么…),则需要使用初始值对其进行初始化。 i、 e:

让mut temp:Vec=Vec::具有_容量(10);//在内存中为
//10个要素。这个向量
//初始容量10,长度为
//您推入其中的元素数
//(最初为0)
v、 推(1);//现在长度是1,容量仍然是10
vs

让mut v:Vec=Vec![0; 10]; // 创建一个包含10个元素的向量
//已初始化为0。你可以变异
//这些将在稍后到位。
//此时,长度=容量=10
v[0]=1;//将第一个元素变为1。
//长度和容量仍为10

文档只是有点含糊不清。措辞可以更好。您的代码示例与以下等效堆栈一样“安全”:

let mut arr: [T; N] = mem::uninitialized();
这意味着只要在读取数组元素之前先写入它,就可以了。如果你先读后写,你就打开了记忆和不安全的大门

我只是想避免克隆那个vec![0;n]将带来


llvm会将其优化为单个内存集。

不,通常不安全!与其说我在逃避指令,不如说我不必将我的类型限制为
Clone
,这
vec宏需要。我还想保证从
Vec
生成的任何
&mut[T]
都具有正确的长度,并且不会导致越界错误。@DanielPath抱歉,我没有看到您问题的最后一部分。@DanielPath我仍然不确定是否理解您的问题。。。除非您在某个地方使用不安全的代码,否则Rust中的引用已经维护了有关vec长度的信息(因此您应该没有越界错误)。下面是我在没有
set\u len
的情况下所做的事情,事情会很恐慌。我需要补偿。@DanielFath好吧,你在做不安全的事…:)在这种情况下,set_length“强制”目标向量被视为已经包含10个元素,因为ptr::copy显然是在长度而不是容量上迭代的
let mut v: Vec<i32> = vec![0; 10]; // create a vector with 10 elements
                                   // initialized to 0. You can mutate
                                   // those in place later.
                                   // At this point, length = capacity = 10

v[0] = 1; // mutating first element to 1.
          // length and capacity are both still 10
let mut arr: [T; N] = mem::uninitialized();