Lua: Language: Table

 9th November 2022 at 3:14pm

Table 是 Lua 中 唯一的数据结构机制(data structuring mechanism)。其他编程语言往往提供更丰富的数据结构,比如 list、class 等,Lua 则用 table 表示一切。

Lua 的 table 是 object。它总是 pass by reference。

> a = {}
> k = "x"
> a[k] = 10
> a[20] = "great"

> a["x"]      --> 10

> k = 20
> a[k]        --> "great"

> a["x"] = a["x"] + 1
> a["x"]      --> 11
> a = {}
> a["x"] = 10
> b = a
> b["x"]       --> 10
> b["x"] = 20
> a["x"]       --> 20
> a.x          --> 20
> a.y          --> nil
> a = nil
> b = nil
-- no references left to the table.
-- the table will eventally be garbage collected.

math.sin() 中的 math 实际上也是个 table。

一个 table 的 key 不需要是同样类型的。意味着你可以有不同的 a[1] a["1"]

一个 float 值作为 key 时,如果它没有小数部分,那么用它对应的整数来访问也是可以的:

> a = {}
> a[1.0] = 100
> a[2] = 200
> a[1]    --> 100
> a[2.0]  --> 200

-- 实际上,一个 float key 如果没有小数部分且值在 integer 范围内,会以整数存
>  for k, v in pairs(a) do
>>   print(k, v)
>> end
1 100
2 200

如果 key 不是合法的 identifier,可以用 [] 包裹起来:

opnames = {["+"] = "add", ["-"] = "sub",
           ["*"] = "mul", ["/"] = "div"}
print(opnames["-"])   --> sub

x = 10
a = { [x] = 100 }
print(a[10])     --> 100
print(a[x])      --> 100

各种方式揉合起来:

i = 5

t = {
    x = 0,        --> t.x 或 t["x"]
    100,          --> t[1]
    ["a"] = 200,  --> t["a"] 或 t.a
    [i] = 300,    --> t[5]
    400,          --> t[2]
}

-- Table traversal:
for k, v in pairs(t) do
    print(k, v)
end

-- 输出(顺序随机):
1   100
2   400
5   300
x   0
a   200

-- Sequence traversal:
for k, v in ipairs(t) do
    print(k, v)
end

-- 输出(顺序固定,且按 sequence 来):
1   100
2   400

追加元素进 table

使用 table.insert(t, x)t 是 table,x 是元素。

原型是 table.insert (table, [pos,] value)pos 表示要插入的位置(1-based)。省略 pos 时表示插入到最后。

Safe navigation

对于一个嵌套多层的 table,访问内层的 key 会需要判空:

zip = company and company.director and
      company.director.address and company.director.address.zipcode

这样写太繁琐,常见的写法是;

zip = (((company or {}).director or {}).address or {}).zipcode

或者更简单的:

E = {}
zip = (((company or E).director or E).address or E).zipcode

Table 判空

if t and next(t) ~= nil then
  -- t is empty
end