如何制作接收大小的矢量?

Ars*_*min 6 rust

我有一个data编译时大小未知的向量.我想创建一个确切大小的新矢量.这些变体不起作用:

let size = data.len();

let mut try1: Vec<u32> = vec![0 .. size]; //ah, you need compile-time constant
let mut try2: Vec<u32> = Vec::new(size); //ah, there is no constructors with arguments
Run Code Online (Sandbox Code Playgroud)

我有点沮丧 - 在Rust API,book,reference或rustbyexample.com中没有关于如何使用vector执行这样简单的基本任务的任何信息.这个解决方案有效,但我不认为这样做很好,一个接一个地生成元素很奇怪,我不需要任何精确的元素值:

let mut temp: Vec<u32> = range(0u32, data.len() as u32).collect();
Run Code Online (Sandbox Code Playgroud)

Chr*_*gan 14

这样做的推荐方法实际上是形成一个迭代器并将其收集到一个向量中.然而,你想要的并不是很清楚; 如果你愿意[0, 1, 2, …, size - 1],你可以创建一个范围并将其收集到一个向量:

let x = (0..size).collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

(现在range(0, size)写的更好(0..size); range功能很快就会从前奏中消失.)

如果你想要一个零向量,你可以这样写:

let x = std::iter::repeat(0).take(size).collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

如果您只想预先分配适当数量的空间但不将值推到矢量上,Vec::with_capacity(capacity)那就是您想要的.

您还应该考虑是否需要它作为向量,或者是否可以直接使用迭代器.

  • @FominArseniy`C++中的新T [n]`执行默认初始化,对于像`int`这样的原语意味着没有初始化,但是调用用户定义类型的默认构造函数.并且C++`std :: vector`也不允许未初始化的值(它不进行边界检查,因此你可以写入保留的内存,但是这是UB,并且在任何情况下,向量都不会将这些元素确认为其大小将保持0). (4认同)

Vla*_*eev 13

您可以使用Vec::with_capacity()构造函数,然后使用不安全的set_len()调用:

let n = 128;
let v: Vec<u32> = Vec::with_capacity(n);
unsafe { v.set_len(n); }
v[12] = 64;  // won't panic
Run Code Online (Sandbox Code Playgroud)

这样,矢量将"延伸"在未初始化的存储器上.如果你打算将它用作缓冲区,那么它是一种有效的方法,只要元素的类型是Copy(原语是好的,但如果类型有析构函数,它会破坏).

  • `set_len`甚至可以在不设置太大的情况下导致内存损坏:数据未初始化并与之交互(除了仅使用`std :: ptr :: write`写入它)可能会导致未定义的行为.(对于`u32`来说,它基本上没问题,但是使用带有析构函数的任何类型的`=`将导致析构函数在"随机"未初始化的内存上运行.) (3认同)