代表可以在执行上下文之间共享的表状数据结构。虽然它可以用于各种类型的一般数据存储,但它专门用于与 Parallel Luau 一起使用,可用于在不同的 例子下分享状态的共享。
有一些 idiomatic 的方法可以在脚本之间通信共享表。一个方法是在 SharedTable 中存储并检索对象 SharedTableRegistry 。注册允许任何在同一数据模型中的脚本获取或设置 SharedTable 名称。另一种方法是使用 Actor:SendMessage() 将共享表发送到另一个 Actor 消信息中。
像 Luau 表一样,一个 SharedTable 对象存储一组键值元素对。与 Luau 表不同,只有选定的对象类型才能存储在共享表中,与 Roblox 引擎中其他的限制类似。
钥匙必须是 (1) 字符串或 (2) 小于 2 32 的非负整数数字。其他类型的钥匙不支持。
值必须属于以下类型之一:Boolean、Number、Vector、String、SharedTable 或可序列化的数据输入。能够将 SharedTable 存储为另一个 SharedTable 的值,允许建造递归和递环数据结构。
对象是不同的,不同的对象永远不会相等,即使它们有相同的内容。
像 Luau 表一样,一个 SharedTable 对象可能被冻结,在此情况下它是可读的。试图修改冻结的 SharedTable 将会发生错误。一个冻结的 SharedTable 可以通过先创建一个(非冻结、可修改)SharedTable 包含所需内容,然后调用 SharedTable.cloneAndFreeze() 来创建一个冻结副本来实现。
代码示例
Elements in a SharedTable are accessed in the same way as elements of Luau tables, using the st[k] syntax or, for string keys, st.k.
local st = SharedTable.new()
st[1] = "a"
st["x"] = true
st.y = 5
assert(st[1] == "a")
assert(st["x"] == true)
assert(st.x == true)
assert(st["y"] == 5)
assert(st.y == 5)
-- true is not a valid SharedTable key, so attempting to set that key
-- fails:
assert(not pcall(function() st[true] = 100 end))
-- A function is not a valid SharedTable value, so attempting to set a
-- value to a function fails:
assert(not pcall(function() st["f"] = function() end end))
The for loop can be used to iterate over the elements of a SharedTable. The elements of the SharedTable are not iterated directly. Instead, a shallow clone is made of the SharedTable, and its elements are iterated. This is done to ensure that a consistent view of the SharedTable is maintained throughout the iteration. Thus, both of the following for loops have the same behavior.
Note that this means that if the SharedTable is accessed directly from within the body of the iteration loop, its state may not be consistent with the state observed through the iteration.
The iteration order is partially specified. Elements with numeric keys are iterated before elements with string keys. Elements with numeric keys are iterated in ascending numeric order. Elements with string keys are iterated in an unspecified order.
local st = SharedTable.new({"a", "b", "c"})
for k, v in SharedTable.clone(st, false) do
print(k, ": ", v)
end
for k, v in st do
print(k, ": ", v)
end
概要
构造工具
- new()
返回一个新的、空的 SharedTable。
返回一个新的 SharedTable 包含与提供的 Luau 表中的元素相等的元素。
职能
从 SharedTable 中移除所有元素。
创建并返回提供的 SharedTable 的克隆。
创建并返回提供的 SharedTable 的冻结(仅读)克隆。
添加 delta 到提供的键值中,并返回原始值。
返回 true 如果 SharedTable 被冻结 (只读)。
返回存储在 SharedTable 中的元素数。
通过提供的更新函数更新值与提供的键的值。
构造工具
new
返回一个新的 SharedTable 包含与提供的 Luau 表中的元素相等的元素。
如果提供的 Luau 表包含任何无法存储在 SharedTable 中的键或值,那么构建 SharedTable 将失败。查看本页顶部的摘要,获得可以存储在 SharedTable 中的对象类型列表。如果 Luau 表包含任何表作为值,该表将转换为新的 SharedTable 。
local t = {}t.x = 1t.y = 2t.z = {"a", "b", "c"}local st = SharedTable.new(t)assert(st.x == 1)assert(st.y == 2)assert(st.z[1] == "a")assert(st.z[2] == "b")assert(st.z[3] == "c")
请注意,在某些情况下,可能需要将 SharedTable 存储在 SharedTableRegistry 中。Class.ShareTableRegistry:GetSharedTable() 方法提供了一个方便的方法来实现这一目标。
参数
其元素将被存储在新的 SharedTable 中的 Luau 表。
职能
clear
原子地删除所有元素从 SharedTable 。
如果 SharedTable 被冻结,操作失败,错误将被提升。
local st = SharedTable.new({"a", "b", "c"})assert(SharedTable.size(st) == 3)SharedTable.clear(st)assert(SharedTable.size(st) == 0)
参数
需要清除的 SharedTable 。
返回
clone
创建一个克隆的 SharedTable 并返回克隆。
如果可选的 deep 参数不存在,或者如果存在且其值为 false ,那么将创建浅克隆。浅级克隆只复制最高级别的 SharedTable 对象。如果 SharedTable 自身的任何值是 SharedTable ,那么原始的 SharedTable 和克隆的 SharedTable 都会指向相同的 SharedTable 。
浅克隆操作是原子的,因此克隆 SharedTable 将包含原始 SharedTable 状态的一致截图,即使它同时被其他脚本修改。
如果可选的 deep 参数存在且其值为 true ,那么将创建深度克隆。深度克隆可以递归地复制 SharedTable 对象的结构,使原始 SharedTable 和克隆之间没有共享状态。
图中每个 对象的克隆是原子的,但整体深克隆不是原子的。因此,图中每个 的克隆将包含与原始 对象相同的状态截图,但不同对象的状态可能不一致,如果图在同时修改其他脚本时修改图。
被克隆的 SharedTable 对象可能是冻结的(仅读)或不是。无论如何,新创建的克隆人是 不被冻结(因此可以修改)。要创建冻结克隆人,请使用 SharedTable.cloneAndFreeze 函数。
为了说明浅克隆和深克隆之间的区别,请考虑以下示例。第一个样本创建浅克隆,第二个创建深克隆。
参数
要克隆的 SharedTable 对象。
是否创建深度克隆(true)或浅度克隆(false)。
代码示例
This code sample creates a shallow clone of a SharedTable.
local original = SharedTable.new()
original["a"] = "original a"
original["b"] = "original b"
original["c"] = SharedTable.new()
original["c"]["d"] = "original d"
local clone = SharedTable.clone(original, false)
clone["a"] = "new a"
clone["b"] = "new b"
clone["c"]["d"] = "new d"
assert(original["a"] == "original a")
assert(original["b"] == "original b")
-- Because this was a shallow clone, original["c"] and clone["c"] are
-- the same SharedTable object.
assert(original["c"] == clone["c"])
assert(original["c"]["d"] == "new d")
This code sample creates a deep clone of a SharedTable.
local original = SharedTable.new()
original["a"] = "original a"
original["b"] = "original b"
original["c"] = SharedTable.new()
original["c"]["d"] = "original d"
local clone = SharedTable.clone(original, true)
clone["a"] = "new a"
clone["b"] = "new b"
clone["c"]["d"] = "new d"
assert(original["a"] == "original a")
assert(original["b"] == "original b")
-- Because this was a deep clone, clone["c"] is a clone of original["c"];
-- they are distinct SharedTable objects.
assert(original["c"] ~= clone["c"])
assert(original["c"]["d"] == "original d")
cloneAndFreeze
创建一个冰冻(只读)的克隆 SharedTable 并返回克隆。该函数的行为与克隆函数的行为相同,除了克隆被冻结。
如果需要深度克隆,那么所有克隆的 SharedTable 对象都会被冻结。
参数
要克隆的共享表对象。
是否创建深度克隆(true)或浅度克隆(false)。
increment
原子增加元素的值。具有指定键的元素必须存在于 SharedTable 中,且必须为类型 number 。指定的 delta 被添加到值,原始值返回。
SharedTable.update 函数也可用于这一目的;此 increment 函数存在于方便和性能(一般来通用,increment 比 update 快得多,因此在可能的情况下应该优先使用)。以下两个函数调用具有相同的效果:
local st = SharedTable.new()
st["x"] = 1
local oldValue = SharedTable.increment(st, "x", 1)
SharedTable.update(st, "x", function(v)
oldValue = v
return v + 1
end)
如果 SharedTable 被冻结,操作失败,错误将被提升。
参数
返回
元素的原始值,在 delta 被添加到它之前。
代码示例
This code sample demonstrates usage of SharedTable.increment().
local st = SharedTable.new()
st["x"] = 1
local oldValue = SharedTable.increment(st, "x", 1)
assert(oldValue == 1)
assert(st["x"] == 2)
-- The value of the specified key must be a number. If it is not a
-- number, the call will fail:
st["y"] = "test"
assert(not pcall(function() SharedTable.increment(st, "y", 1) end))
isFrozen
返回 true 如果 SharedTable 被冻结 (只读)。
local st1 = SharedTable.new({"a", "b", "c"})assert(not SharedTable.isFrozen(st1))local st2 = SharedTable.cloneAndFreeze(st1)assert(SharedTable.isFrozen(st2))
参数
被要求查询其冻结状态的 SharedTable 对象。
返回
size
返回共享表中存储的元素数。请注意,如果其他脚本同时修改共享表,返回的大小可能在返回后不再正确,因为其他脚本可能已从共享表中添加或删除元素。
local st = SharedTable.new({"a", "b", "c"})assert(SharedTable.size(st) == 3)st[2] = nilassert(SharedTable.size(st) == 2)
参数
要查询的 SharedTable 对象的大小。
返回
update
原子更新元素的值。
当从不同执行上下文中运行的脚本访问 SharedTable 时,它们的访问可能会交叉不可预测地。因此,以下代码通常不正确,因为值可能在第一行阅读和第二行更新之间发生了变化:
local oldValue = st["x"]st["x"] = oldValue .. ",x"
更新函数使得可以对元素进行原子更新。它需要一个函数,该函数将与元素的当前值调用。函数可以计算并返回新值。请注意,如果 SharedTable 被从其他脚本并行修改,那么函数可能需要多次调用。
如果 SharedTable 被冻结,操作失败,错误将被提升。
参数
返回
代码示例
This code sample demonstrates usage of SharedTable.update().
local st = SharedTable.new()
st["x"] = "abcd"
SharedTable.update(st, "x", function(v)
assert(v == "abcd")
return v .. "e"
end)
assert(st["x"] == "abcde")