如果我们需要FIFO或LIFO集合(基本上push
,pop
和front
/ back
),我们应该在Rust中使用什么?类似于C ++中的std::queue
或std::stack
。
答案 0 :(得分:21)
首先,Rust不提供(在标准库中)任何具有添加元素延迟的库:Rust集合通常可以在添加新元素时分配内存,并且分配内存可能需要在最坏的情况下,无限的时间。
话虽如此,每个案件都有两个竞争者:
Vec
或LinkedList
之上实现堆栈(功能pop_back
和push_back
)VecDeque
或LinkedList
之上实现(功能pop_front
和push_back
) Vec*
和LinkedList
之间的区别在于后者是简单的:每次调用push_back
都会进行内存分配。一方面,这很好,因为这意味着push_back
的成本与集合中已有元素的数量无关,另一方面......内存分配可能需要很长时间
前者有点复杂:
push_back
push_back
一般来说,我建议将Vec
用于堆栈,将VecDeque
用于队列。
答案 1 :(得分:9)
VecDeque
和LinkedList
都有push
/ pop
_ front
/ back
。
答案 2 :(得分:2)
Matthieu M.几乎完美。 Vec
是您的堆栈(LIFO),VecDeque
是一个双端队列,它使用以下方式支持所有4个变体(FIFO,FILO,LIFO和LILO):
.push_front(x) | .front() | .pop_front()
.push_back(x) | .back() | .pop_back()
如果您想最大程度地提高效率,建议您参考"Unterstanding Rust’s Vec and its capacity for fast and efficient programs"。它详细介绍了如何在Vec
和VecDeque
中进行分配和重新分配,但是最大的收获是,如果您可以预测在数据库中需要的最大元素数量,如果知道何时初始化队列,则可以使用VecDeque::with_capacity(x)
队列,如果某个时刻您确切知道将需要多少 个插槽,可以使用.reserve_exact(x)
我强烈建议您查看std::collections
上的Rust文档,其中列出了Rust中最常用的收藏集,以及有关何时选择它们的建议
最后一件事,VecDeque
不是Rust中默认序言的一部分,因此,如果要使用它,则需要包括以下内容:
use std::collections::VecDeque;