【问题标题】:How to allocate space for a Vec<T> in Rust?如何在 Rust 中为 Vec<T> 分配空间?
【发布时间】:2014-11-27 16:56:08
【问题描述】:

我想创建一个Vec&lt;T&gt; 并为其腾出一些空间,但我不知道该怎么做,而且令我惊讶的是,官方文档中几乎没有关于这个基本类型的内容。

let mut v: Vec<i32> = Vec<i32>(SIZE); // How do I do this ?

for i in 0..SIZE {
    v[i] = i;
}

我知道我可以创建一个空的Vec&lt;T&gt; 并用pushes 填充它,但我不想这样做,因为我并不总是知道,在索引i 处写入值时,如果一个值已经被插入到那里。出于明显的性能原因,我不想写类似:

if i >= len(v) {
    v.push(x);
} else {
    v[i] = x;
}

当然,我也不能使用vec! 语法。

【问题讨论】:

  • 如果您正在创建一个新向量,您知道一个值是否存在。请注意,这里的很多答案都假设您正在创建一个新向量,如果不是这种情况(从问题的第二部分看来不是),最好做更多问题中明确。与现有向量相比,新向量的答案大不相同。

标签: vector rust


【解决方案1】:

虽然接受答案中的vec![elem; count] 足以创建一个所有元素都等于相同值的向量,但还有其他便利功能。

Vec::with_capacity() 创建一个具有给定容量但长度为零的向量。这意味着在达到此容量之前,push() 调用不会重新分配向量,从而使push() 基本上是免费的:

fn main() {
    let mut v = Vec::with_capacity(10);
    for i in 0..10 {
        v.push(i);
    }
    println!("{:?}", v);
}

您还可以轻松地collect() 来自迭代器的向量。示例:

fn main() {
    let v: Vec<_> = (1..10).collect();
    println!("{:?}", v);
}

最后,有时你的向量包含原始类型的值,应该用作缓冲区(例如在网络通信中)。在这种情况下你可以使用Vec::with_capacity() + set_len() unsafe 方法:

fn main() {
    let mut v = Vec::with_capacity(10);
    unsafe { v.set_len(10); }
    for i in 0..10 {
        v[i] = i;
    }
    println!("{:?}", v);
}

请注意,如果您的向量包含带有析构函数或引用的值,则必须格外小心 - 很容易让析构函数在未初始化的内存块上运行或以这种方式获得无效的引用。如果您只使用向量的初始化部分,它也可以正常工作(您现在必须自己跟踪它)。要了解未初始化内存的所有可能危险,您可以阅读mem::uninitialized() 的文档。

【讨论】:

  • set_len 可以与非Copy 类型一起正常工作:您只需要小心。它可以被Copy 类型破坏,例如&amp;intCopy,但随机未初始化的内存很可能不是有效的 &amp;int。 (非常危险!)
  • @dbaupp,是的,我可能没有正确表述它。谢谢!
  • 用枚举遍历向量可能会更好,因此不需要检查每个赋值。 (可能会优化边界检查 - 但这取决于循环的复杂性)
【解决方案2】:

您可以使用the vec! macro 的第一个语法,特别是vec![elem; count]。例如:

vec![1; 10]

将创建一个包含 10 个1s 的Vec&lt;_&gt;(类型_ 稍后确定或默认为i32)。赋予宏的elem 必须实现Clonecount 也可以是变量。

【讨论】:

  • 谢谢。好吧,它在文档中。但是,当我搜索它时找不到它。
  • 这不再有效,该方法似乎已被删除。
  • @Rory 现在运行 1.0
  • 这比 ::with_capacity() 更容易记住; .. vec![0; 10];它适用于最新的 Rust 1.4.4
【解决方案3】:

Vec::resize方法:

fn resize(&mut self, new_len: usize, value: T)

此代码通过填充值 7 将空向量的大小调整为 1024 个元素:

let mut vec: Vec<i32> = Vec::new();
vec.resize(1024, 7);

【讨论】:

  • 值得注意的是,这仅在您分配相同的值时才有效 - OP 分配增加的索引。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多