个人学习笔记,如果有误请留言讨论
表
概念
Lua的表可以理解为一种类似哈希表的数据结构,使用键值对来存储元素,当不指定某个值的key时,table会把其当作数组元素处理,数组元素在表中键为1, 2, 3…,注意这里数组是从1开始的而非0 。
赋值
这样可以简单地为表赋初值:
table1 = {1, 2, 3}
table2 = {["w"] = "foo", ["a"] = "bar", ["o"] = "ha"}
注意:
在赋初值的时候,表遵循先为键值对创建空间,再为数组创建空间的原则,也就是说如果键值对的键与数组的键重合了,会被覆盖掉。
-- 表中元素为fooArray和bar
local table = {"fooArray", ["1"] = "bar", [1] = "fooHash"}
遍历
常见的有pairs和ipairs两种方法:
- pairs会遍历表中所有不为空的值。
- 而ipairs前的i意为int,其会像遍历数组一样,从下标1开始遍历,中间遇到nil值就会停止遍历。
例子:
local table = {[0] = 0, 1, 2, nil, 4}
for _, v in pairs(table) do
print(v) -- 1 2 4 0
end
print("----------")
for _, v in ipairs(table) do
print(v) -- 1 2
end
元表
概念
元表是一种与特定表相关联,描述/改变关联表的行为的表,这里的行为包含访问、插入、加减乘除等,可以理解为重载。
通过给元表的特殊字段赋值来实现上述重载。
设置/获取关联
table = {}
metaTable = {}
setmetatable(table, metaTable) -- 将metaTable设置为table的元表
tmpMetaTable = getmetatable(table) -- 获取table的元表
__index字段和__newindex字段
__index字段规定了在表中查找一个不存在的key时的行为,既可以是一个表也可以是一个函数,如果是表的话会在__index对应的表中继续寻找key,如果是函数则会调用此函数。此字段常用于解决默认值问题。
例子:
table = {"hey1", "hey2", "hey3"}
tmp = {[10] = "here's tmp"}
metaTable = {__index = tmp}
setmetatable(table, metaTable)
-- here's tmp
print(table[10])
function myIndex(table, index)
print("Can't find", index)
return table[1]
end
metaTable.__index = myIndex
-- Can't find 10
-- hey1
print(table[10])
__newindex字段对应的元方法会在表中插入一个之前没有的key时调用,一般用来监测表中插入新字段的操作。需要注意的是__newindex中不能对表进行直接赋值,否则还会调用__newindex,形成无限的递归。但是可以使用rawset函数,绕过__newindex进行赋值。
例子:
table = {}
setmetatable(table, {__newindex = function(table, key, value)
print("Insert new pair")
rawset(table, key, value .. "tttttt")
end
})
table["tmp"] = "tmp" -- Insert new pair
print(table["tmp"]) -- tmptttttt
__add字段与其他二元操作符
定义了表在相加时的行为,另一个相加数可以是基本类型、也可以是另一张表。
注意: 如果两个加数都是表,并且两表的元表中都有__add字段,默认使用“+”左边的表的规则。如果只有一张表有__add字段,那么就使用这张表定义的规则。
myTable1 = {1, 2, 3}
metaTable = {}
setmetatable(myTable1, metaTable)
-- 与数字相加
function myAdd1(table, num)
for i,v in ipairs(table) do
table[i] = v + num
print(table[i])
end
end
metaTable.__add = myAdd1
t = myTable1 + 1 -- 2 3 4
-- 两表相加
metaTable.__add = function()
print("table1")
end
myTable2 = {3, 2, 1}
setmetatable(myTable2, {__add = function()
print("table2")
end})
tmp = myTable1 + myTable2 -- table1
其他的二元操作符如下:
字段 | 描述 |
---|---|
__sub | 减法 |
__mul | 乘法 |
__div | 除法 |
__mod | 取模 |
__unm | 相反数 |
__concat | 连接(…) |
__eq | 等于 |
__lt | 小于 |
__le | 小于等于 |
__call字段与__tostring字段
call字段让表可以像函数一样被调用:
table = {"111", "222"}
function call(table, index)
return table[index]
end
setmetatable(table, {__call = call})
print(table(2)) -- 222
tostring字段控制表转换为字符串的规则:
table = {"111", "222"}
function myToString(table)
res = ""
for _, v in pairs(table) do
res = res .. tostring(v)
end
return res
end
setmetatable(table, {__tostring = myToString})
print(table) -- 111222