Lua中的数据结构——表

表是Lua语言中最主要(事实上也是唯一的)和强大的数据结构。

Lua语言中的表本质上是一种辅助数组,这种数组不仅可以使用数值作为索引,也可以使用字符串或其他任意类型的值作为索引(nil除外)。

Lua语言的表要么是值要么是变量,它们都是对象,表是一种动态分配的对象,程序只能操作指向表的引用。除此之外,Lua语言不会进行隐藏的拷贝(深拷贝:拷贝对象的引用而非整个对象本身)或创建新的表。

表永远是匿名的,表本身和保存表的变量之间没有固定的关系。

对于一个表而言,当程序中不再有指向它的引用时,垃圾收集器会最终删除这个表并重用其占用的内存。

表索引

同一个表中存储的值可以具有不同的类型索引,并可以按需增长容纳新的元素。

把表当作结构体使用时,可以把索引当作成员名称使用(a.name等价于a[“name”]),但一般点分形式说明了表时被当作结构体使用的,此时表实际上是由固定的、预先定义的键组成的集合

注意:a.x表示的是a.[“x”],而不是a[x],a[x]是指由变量x对应的值索引的表。

当被用作表索引是,任何能够被转换为整型的浮点数都会被转换成整型数;相反,不能被转换为整型数的浮点数则不会发生上述的类型转换。(这里的”能够被转换“指的是2.0这种数值本身就是整数的值)

表构造器

表构造器用来创建和初始化表的表达式。

  • 列表式写法:days = {1,2,3,4,5,6,7}
  • 记录式写法:a = {x = 10, y = 20}

不能使用负数索引初始化列表(索引必须从1开始),也不能使用不符合规范的标识符作为索引。可以使用另一种更加通用的构造器,即通过方括号扩起来的表达式显示的指定每一个索引:opnames = {["+"] = "add",["-"] = "sub",["*"] = "mul",["/"] = "div"}

数组、列表和序列

只需要使用整型作为索引即可表示常见的数组或列表,Lua中数组索引依照惯例是从1开始的。

  • 我们把所有元素都不为nil的数组称为序列。Lua语言提供了操作符#来获取序列的长度。
  • 对于中间存在空洞(nil值)的列表而言,序列长度操作符是不可靠的,它只能用于序列。
  • 不包含数值类型键的表就是长度为零的序列。
  • 对于Lua语言来说,一个nil的字段和一个不存在的元素没有区别,因此a = {10,20,30,nil,nil}的长度为3,而非5。

遍历表

  • 可以使用pairs迭代器遍历表中的键值对,但它遍历过程中元素的出现顺序可能是随机的,相同的程序在每次运行时也可能产生不同的顺序,但在遍历的过程中,每个元素会且仅会出现一次。
  • 对于列表而言,可以使用ipairs迭代器,这会是顺序进行遍历的。
  • 可以使用数值型for循环来遍历序列。

安全访问

对于表达式a or {},当a为nil时,其结果是一个空表,因此对于表达式(a or {}).b,当a为

nil时其结果也同样是nil,这样就可以写成:zip = (((company or {}).director or {}).address or {}).zipcode

表标准库: