队列是一种线性数据结构,包含一组项。Roblox上有两种类型的队列:常规队列,遵循先进先出(FIFO)原则,以及优先队列,其队列中的项具有优先级,决定了数据访问的顺序。两种类型的队列中的项可以是任何Luau 数据类型。
队列是名为 MemoryStoreService 的非持久性数据存储服务的内置数据结构,您可以直接调用内置函数来获取队列,并向队列中添加、读取或移除数据。对于其他用法,例如调度任务和处理游戏中的请求,您可以使用表格来自己实现队列。
常规队列
常规队列以FIFO顺序维护,其中所有项都会被添加到队列的末尾,并按照添加的顺序从前到后读取或移除。

优先队列
优先队列不遵循FIFO规则,其中每个项可以添加一个优先级数字,指示其被读取或移除的顺序。优先队列末尾的项具有默认优先级0,队列前面的项具有最高设置的优先级,在以下示例中为5。

在这个示例中,一个设置优先级为3的项被添加到队列中。队列将新的项放置在所有具有设置优先级为3或更高的现有项之后。要将某个项放在队列的前面,您需要将优先级设置得高于当前最高的设置优先级。在这个示例中,您需要将优先级设置为6或更高。
优先队列对于您希望根据重要性顺序而不是添加顺序读取或访问数据的情况非常有用。您可以在添加项时将优先级设置为整数,队列会在处理项时优先处理高优先级的项,而不是低优先级的项。例如,您可以通过为等待时间较长的用户分配更高的优先级,使用优先队列进行匹配。
实现队列
您可以使用 MemoryStoreService 的内置队列,或者使用表来实现其他所有用法的队列。以下代码示例显示了常规队列的实现。要在您的游戏中使用此实现,您应该将其保存为 ModuleScript 并存储在 ReplicatedStorage 中,以便您的队列可以被客户端和服务器访问。
使用表实现常规队列
--!strict
local Queue = {}
Queue.__index = Queue
export type Queue<T> = typeof(setmetatable(
{} :: {
_first: number,
_last: number,
_queue: { T },
},
Queue
))
function Queue.new<T>(): Queue<T>
local self = setmetatable({
_first = 0,
_last = -1,
_queue = {},
}, Queue)
return self
end
-- 检查队列是否为空
function Queue.isEmpty<T>(self: Queue<T>)
return self._first > self._last
end
-- 向队列添加一个值
function Queue.enqueue<T>(self: Queue<T>, value: T)
local last = self._last + 1
self._last = last
self._queue[last] = value
end
-- 从队列中移除一个值
function Queue.dequeue<T>(self: Queue<T>): T
if self:isEmpty() then
error("无法从空队列中出队")
end
local first = self._first
local value = self._queue[first]
self._queue[first] = nil
self._first = first + 1
return value
end
return Queue
以下代码示例是作为 Script 在 Workspace 下的用法示例。您可以根据自己的用法修改代码、类型和存储位置,只要先前的实现代码正确存储即可。
常规队列使用示例local ReplicatedStorage = game:GetService("ReplicatedStorage")local Queue = require(ReplicatedStorage:WaitForChild("Queue"))local myQueue = Queue.new()-- 向队列添加一些值myQueue:enqueue(5)myQueue:enqueue(10)myQueue:enqueue(15)-- myQueue = { 5, 10, 15 }-- 从队列中移除一个值local first = myQueue:dequeue()print("添加到队列的第一个值是", first)-- myQueue = { 10, 15 }-- 向队列添加更多值myQueue:enqueue(20)myQueue:enqueue(25)myQueue:enqueue(30)-- myQueue = { 10, 15, 20, 25, 30 }-- 再次从队列中移除一个值local second = myQueue:dequeue()print("添加到队列的第二个值是", second)-- myQueue = { 15, 20, 25, 30 }